From 7c7c76f6b3a0a762496e46d3446f995077d6bb81 Mon Sep 17 00:00:00 2001 From: aribeiro Date: Mon, 5 Oct 2020 10:45:11 +0100 Subject: Fix node filter capability filters Issue-ID: SDC-3335 Signed-off-by: aribeiro Change-Id: I6ffc1e0fb079ac0e33262f16a62deefda97f7616 Signed-off-by: aribeiro (cherry picked from commit 1ae28c3a8b33e286331608e1c4a1e3cc483699eb) --- .../impl/ComponentNodeFilterBusinessLogic.java | 157 ++++++--------------- .../ComponentSubstitutionFilterBusinessLogic.java | 3 +- .../components/validation/NodeFilterValidator.java | 157 +++++++++++++++------ .../be/datamodel/utils/ConstraintConvertor.java | 52 +++++-- .../be/servlets/ComponentNodeFilterServlet.java | 73 +++++----- .../sdc/be/tosca/utils/NodeFilterConverter.java | 24 +++- 6 files changed, 253 insertions(+), 213 deletions(-) (limited to 'catalog-be/src/main/java') 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 1b9054e187..f547dcf19c 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 @@ -24,9 +24,8 @@ 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.apache.commons.lang.StringUtils; 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; @@ -50,6 +49,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.model.UIConstraint; import org.openecomp.sdc.be.user.Role; import org.openecomp.sdc.common.log.wrappers.Logger; import org.openecomp.sdc.exception.ResponseFormat; @@ -177,12 +177,13 @@ public class ComponentNodeFilterBusinessLogic extends BaseBusinessLogic { final String constraint, final boolean shouldLock, final ComponentTypeEnum componentTypeEnum, - final NodeFilterConstraintType nodeFilterConstraintType) + final NodeFilterConstraintType nodeFilterConstraintType, + final String capabilityName) throws BusinessLogicException { final Component component = getComponent(componentId); CINodeFilterDataDefinition nodeFilterDataDefinition = validateAndReturnNodeFilterDefinition(componentInstanceId, - action, constraint, component); + action, constraint, component, nodeFilterConstraintType); boolean wasLocked = false; try { if (shouldLock) { @@ -193,9 +194,10 @@ public class ComponentNodeFilterBusinessLogic extends BaseBusinessLogic { new RequirementNodeFilterPropertyDataDefinition(); requirementNodeFilterPropertyDataDefinition.setName(propertyName); requirementNodeFilterPropertyDataDefinition.setConstraints(Collections.singletonList(constraint)); + final Either result = addNewNodeFilter(componentId, - componentInstanceId, propertyName, nodeFilterConstraintType, nodeFilterDataDefinition, - requirementNodeFilterPropertyDataDefinition); + componentInstanceId, nodeFilterConstraintType, nodeFilterDataDefinition, + requirementNodeFilterPropertyDataDefinition, capabilityName); if (result.isRight()) { janusGraphDao.rollback(); throw new BusinessLogicException(componentsUtils.getResponseFormatByResource(componentsUtils @@ -232,7 +234,7 @@ public class ComponentNodeFilterBusinessLogic extends BaseBusinessLogic { final Component component = getComponent(componentId); CINodeFilterDataDefinition nodeFilterDataDefinition = - validateAndReturnNodeFilterDefinition(componentInstanceId, action, constraint, component); + validateAndReturnNodeFilterDefinition(componentInstanceId, action, constraint, component, nodeFilterConstraintType); boolean wasLocked = false; try { if (shouldLock) { @@ -266,90 +268,13 @@ public class ComponentNodeFilterBusinessLogic extends BaseBusinessLogic { return Optional.ofNullable(nodeFilterDataDefinition); } - public Optional updateNodeFilter(final String componentId, - final String componentInstanceId, - final List constraints, - final boolean shouldLock, - final ComponentTypeEnum componentTypeEnum, - final NodeFilterConstraintType nodeFilterConstraintType) - throws BusinessLogicException { - - final Component component = getComponent(componentId); - - final Either response = nodeFilterValidator - .validateFilter(component, componentInstanceId, constraints, NodeFilterConstraintAction.UPDATE); - if (response.isRight()) { - throw new BusinessLogicException(componentsUtils - .getResponseFormat(ActionStatus.NODE_FILTER_NOT_FOUND, response.right().value().getFormattedMessage())); - } - final Optional componentInstance = getComponentInstance(componentInstanceId, - component); - if (!componentInstance.isPresent()) { - throw new BusinessLogicException(ResponseFormatManager.getInstance() - .getResponseFormat(ActionStatus.GENERAL_ERROR)); - } - CINodeFilterDataDefinition nodeFilterDataDefinition = componentInstance.get().getNodeFilter(); - if (nodeFilterDataDefinition == null) { - throw new BusinessLogicException(componentsUtils.getResponseFormat(ActionStatus.NODE_FILTER_NOT_FOUND)); - } - boolean wasLocked = false; - try { - if (shouldLock) { - lockComponent(component.getUniqueId(), component,"Update Node Filter on Component"); - wasLocked = true; - } - final Either result = - updateNodeFilterConstraint(componentId, componentInstanceId, constraints, nodeFilterConstraintType, - nodeFilterDataDefinition); - - if (result.isRight()) { - janusGraphDao.rollback(); - throw new BusinessLogicException(componentsUtils.getResponseFormatByResource(componentsUtils - .convertFromStorageResponse(result.right().value()), component.getSystemName())); - } else { - nodeFilterDataDefinition = result.left().value(); - } - janusGraphDao.commit(); - LOGGER.debug("Node filter successfully updated in component {} . ", component.getSystemName()); - - } catch (final Exception e) { - janusGraphDao.rollback(); - LOGGER.error(BUSINESS_PROCESS_ERROR, - "Exception occurred during update component node filter property values: {}", - e.getMessage(), e); - throw new BusinessLogicException(componentsUtils.getResponseFormat(ActionStatus.GENERAL_ERROR)); - - } finally { - if (wasLocked) { - unlockComponent(component.getUniqueId(), componentTypeEnum); - } - } - return Optional.ofNullable(nodeFilterDataDefinition); - } - - private Either updateNodeFilterConstraint( - final String componentId, final String componentInstanceId, final List constraints, - final NodeFilterConstraintType nodeFilterConstraintType, final CINodeFilterDataDefinition nodeFilterDataDefinition) { - - if (NodeFilterConstraintType.PROPERTIES.equals(nodeFilterConstraintType)) { - final List properties = constraints.stream() - .map(this::getRequirementNodeFilterPropertyDataDefinition).collect(Collectors.toList()); - return nodeFilterOperation.updateProperties(componentId, componentInstanceId, - nodeFilterDataDefinition, properties); - } - final List capabilities = constraints.stream() - .map(this::getRequirementNodeFilterCapabilityDataDefinition).collect(Collectors.toList()); - return nodeFilterOperation.updateCapabilities(componentId, componentInstanceId, - nodeFilterDataDefinition, capabilities); - } - private Either addNewNodeFilter( final String componentId, final String componentInstanceId, - final String propertyName, final NodeFilterConstraintType nodeFilterConstraintType, final CINodeFilterDataDefinition nodeFilterDataDefinition, - final RequirementNodeFilterPropertyDataDefinition requirementNodeFilterPropertyDataDefinition) { + final RequirementNodeFilterPropertyDataDefinition requirementNodeFilterPropertyDataDefinition, + final String capabilityName) { if (NodeFilterConstraintType.PROPERTIES.equals(nodeFilterConstraintType)) { return nodeFilterOperation.addNewProperty(componentId, componentInstanceId, nodeFilterDataDefinition, @@ -357,7 +282,7 @@ public class ComponentNodeFilterBusinessLogic extends BaseBusinessLogic { } final RequirementNodeFilterCapabilityDataDefinition requirementNodeFilterCapabilityDataDefinition = new RequirementNodeFilterCapabilityDataDefinition(); - requirementNodeFilterCapabilityDataDefinition.setName(propertyName); + requirementNodeFilterCapabilityDataDefinition.setName(capabilityName); final ListDataDefinition propertyDataDefinitionListDataDefinition = new ListDataDefinition<>(); propertyDataDefinitionListDataDefinition.getListToscaDataDefinition().addAll( @@ -410,37 +335,14 @@ public class ComponentNodeFilterBusinessLogic extends BaseBusinessLogic { return Optional.empty(); } - private RequirementNodeFilterPropertyDataDefinition getRequirementNodeFilterPropertyDataDefinition( - final String constraint) { - - final RequirementNodeFilterPropertyDataDefinition requirementNodeFilterPropertyDataDefinition = - new RequirementNodeFilterPropertyDataDefinition(); - requirementNodeFilterPropertyDataDefinition.setConstraints(Arrays.asList(constraint)); - return requirementNodeFilterPropertyDataDefinition; - } - - private RequirementNodeFilterCapabilityDataDefinition getRequirementNodeFilterCapabilityDataDefinition( - final String constraint) { - - final RequirementNodeFilterCapabilityDataDefinition requirementNodeFilterCapabilityDataDefinition = - new RequirementNodeFilterCapabilityDataDefinition(); - final ListDataDefinition propertyDataDefinitionList = - new ListDataDefinition<>(); - propertyDataDefinitionList.getListToscaDataDefinition().addAll( - Collections.singleton(getRequirementNodeFilterPropertyDataDefinition(constraint))); - requirementNodeFilterCapabilityDataDefinition.setName(new ConstraintConvertor().convert(constraint) - .getServicePropertyName()); - requirementNodeFilterCapabilityDataDefinition.setProperties(propertyDataDefinitionList); - return requirementNodeFilterCapabilityDataDefinition; - } - private CINodeFilterDataDefinition validateAndReturnNodeFilterDefinition(final String componentInstanceId, final NodeFilterConstraintAction action, final String constraint, - final Component component) + final Component component, + final NodeFilterConstraintType nodeFilterConstraintType) throws BusinessLogicException { - validateNodeFilter(component, componentInstanceId, action, constraint); + validateNodeFilter(component, componentInstanceId, action, constraint, nodeFilterConstraintType); final Optional cINodeFilterDataDefinition = getCiNodeFilterDataDefinition( componentInstanceId, component); if (!cINodeFilterDataDefinition.isPresent()) { @@ -452,12 +354,37 @@ public class ComponentNodeFilterBusinessLogic extends BaseBusinessLogic { private void validateNodeFilter(final Component component, final String componentInstanceId, final NodeFilterConstraintAction action, - final String constraint) throws BusinessLogicException { + final String constraint, + final NodeFilterConstraintType nodeFilterConstraintType) throws BusinessLogicException { final Either response = nodeFilterValidator - .validateFilter(component, componentInstanceId, Collections.singletonList(constraint), action); + .validateFilter(component, componentInstanceId, Collections.singletonList(constraint), action, nodeFilterConstraintType); if (response.isRight()) { throw new BusinessLogicException(componentsUtils .getResponseFormat(ActionStatus.NODE_FILTER_NOT_FOUND, response.right().value().getFormattedMessage())); } } + + public Optional updateNodeFilter(final String componentId, + final String componentInstanceId, + final UIConstraint uiConstraint, + final ComponentTypeEnum componentTypeEnum, + final NodeFilterConstraintType nodeFilterConstraintType, + final int index) + throws BusinessLogicException { + + final Optional deleteActionResponse = deleteNodeFilter(componentId, + componentInstanceId, + NodeFilterConstraintAction.DELETE, null, index, true, componentTypeEnum, + nodeFilterConstraintType); + + if (!deleteActionResponse.isPresent()) { + 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, + StringUtils.isEmpty(uiConstraint.getCapabilityName()) ? "" : uiConstraint.getCapabilityName()); + } } 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 74de13c952..c02db7a9e3 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 @@ -68,8 +68,7 @@ public class ComponentSubstitutionFilterBusinessLogic extends BaseBusinessLogic final InterfaceLifecycleOperation interfaceLifecycleTypeOperation, final ArtifactsOperations artifactToscaOperation, final SubstitutionFilterOperation substitutionFilterOperation, - NodeFilterValidator nodeFilterValidator) - { + final NodeFilterValidator nodeFilterValidator) { super(elementDao, groupOperation, groupInstanceOperation, groupTypeOperation, interfaceOperation, interfaceLifecycleTypeOperation, artifactToscaOperation); this.substitutionFilterOperation = substitutionFilterOperation; 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 c6848030cd..8c27396e3b 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 @@ -28,13 +28,16 @@ import java.util.List; import java.util.Objects; import java.util.Optional; import java.util.Set; +import java.util.stream.Collectors; 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.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; @@ -53,11 +56,11 @@ public class NodeFilterValidator { private static final String SOURCE = "Source"; public static final Set comparableTypes = ImmutableSet.of(ToscaPropertyType.STRING.getType(), - ToscaPropertyType.INTEGER.getType(), ToscaPropertyType.FLOAT.getType()); + ToscaPropertyType.INTEGER.getType(), ToscaPropertyType.FLOAT.getType()); public static final Set schemableTypes = - ImmutableSet.of(ToscaPropertyType.MAP.getType(), ToscaPropertyType.LIST.getType()); + ImmutableSet.of(ToscaPropertyType.MAP.getType(), ToscaPropertyType.LIST.getType()); public static final Set comparableConstraintsOperators = - ImmutableSet.of(ConstraintConvertor.GREATER_THAN_OPERATOR, ConstraintConvertor.LESS_THAN_OPERATOR); + ImmutableSet.of(ConstraintConvertor.GREATER_THAN_OPERATOR, ConstraintConvertor.LESS_THAN_OPERATOR); protected final ToscaOperationFacade toscaOperationFacade; protected final ComponentsUtils componentsUtils; @@ -78,8 +81,8 @@ public class NodeFilterValidator { return getErrorResponse(ActionStatus.FILTER_NOT_FOUND); } if (CollectionUtils.isEmpty(component.getComponentInstances()) || - component.getComponentInstances().stream() - .noneMatch(ci -> ci.getUniqueId().equals(componentInstanceId))) { + component.getComponentInstances().stream() + .noneMatch(ci -> ci.getUniqueId().equals(componentInstanceId))) { LOGGER.error("Component Instance list is empty"); return getErrorResponse(ActionStatus.FILTER_NOT_FOUND); } @@ -94,20 +97,28 @@ public class NodeFilterValidator { public Either validateFilter(final Component parentComponent, final String componentInstanceId, final List uiConstraints, - final NodeFilterConstraintAction action) { + final NodeFilterConstraintAction action, + final NodeFilterConstraintType nodeFilterConstraintType) { 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 booleanResponseFormatEither = - validatePropertyConstraint(parentComponent, componentInstanceId, constraint); + validatePropertyConstraint(parentComponent, componentInstanceId, constraint); if (booleanResponseFormatEither.isRight()) { return booleanResponseFormatEither; } } else if (ConstraintConvertor.STATIC_CONSTRAINT.equals(constraint.getSourceType())) { - final Either booleanResponseFormatEither = - validateStaticValueAndOperator(parentComponent, componentInstanceId, constraint); + Either booleanResponseFormatEither; + if (NodeFilterConstraintType.PROPERTIES.equals(nodeFilterConstraintType)) { + booleanResponseFormatEither = isComponentPropertyFilterValid( + parentComponent, componentInstanceId, constraint); + } else { + booleanResponseFormatEither = isComponentCapabilityPropertyFilterValid( + parentComponent, componentInstanceId, constraint); + } + if (booleanResponseFormatEither.isRight()) { return booleanResponseFormatEither; } @@ -122,6 +133,21 @@ public class NodeFilterValidator { return Either.left(true); } + private Either isComponentCapabilityPropertyFilterValid(final Component parentComponent, + final String componentInstanceId, + final UIConstraint uiConstraint) { + + return validateStaticValueAndOperatorOfCapabilityProperties(parentComponent, componentInstanceId, uiConstraint); + + } + + private Either isComponentPropertyFilterValid(Component parentComponent, + String componentInstanceId, + UIConstraint constraint) { + + return validateStaticValueAndOperator(parentComponent, componentInstanceId, constraint); + } + private Either validatePropertyConstraint(final Component parentComponent, final String componentInstanceId, final UIConstraint uiConstraint) { @@ -130,36 +156,36 @@ public class NodeFilterValidator { final List propertyDefinitions = parentComponent.getProperties(); List sourcePropertyDefinition = - parentComponent.getName().equals(uiConstraint.getSourceName()) && - propertyDefinitions != null ? propertyDefinitions : Collections.emptyList(); + parentComponent.getName().equals(uiConstraint.getSourceName()) && + propertyDefinitions != null ? propertyDefinitions : Collections.emptyList(); if (sourcePropertyDefinition.isEmpty() && !parentComponent.getName().equals(uiConstraint.getSourceName())) { optionalComponentInstance = parentComponent.getComponentInstances().stream() - .filter(componentInstance -> uiConstraint.getSourceName() - .equals(componentInstance - .getName())) - .findFirst(); + .filter(componentInstance -> uiConstraint.getSourceName() + .equals(componentInstance + .getName())) + .findFirst(); if (optionalComponentInstance.isPresent()) { final List componentInstanceProperties = - parentComponent.getComponentInstancesProperties() - .get(optionalComponentInstance.get().getUniqueId()); + parentComponent.getComponentInstancesProperties() + .get(optionalComponentInstance.get().getUniqueId()); sourcePropertyDefinition = - componentInstanceProperties == null ? new ArrayList<>() : componentInstanceProperties; + componentInstanceProperties == null ? new ArrayList<>() : componentInstanceProperties; } } if (!CollectionUtils.isEmpty(sourcePropertyDefinition)) { final Optional sourceSelectedProperty = sourcePropertyDefinition.stream() - .filter(property -> uiConstraint - .getValue() - .equals(property.getName())) - .findFirst(); + .filter(property -> uiConstraint + .getValue() + .equals(property.getName())) + .findFirst(); final Optional targetComponentInstanceProperty = - parentComponent.getComponentInstancesProperties().get(componentInstanceId).stream() - .filter(property -> uiConstraint.getServicePropertyName().equals(property.getName())) - .findFirst(); + parentComponent.getComponentInstancesProperties().get(componentInstanceId).stream() + .filter(property -> uiConstraint.getServicePropertyName().equals(property.getName())) + .findFirst(); source = !targetComponentInstanceProperty.isPresent() ? "Target" : SOURCE; if (sourceSelectedProperty.isPresent() && targetComponentInstanceProperty.isPresent()) { @@ -168,10 +194,10 @@ public class NodeFilterValidator { } final String missingProperty = - source.equals(SOURCE) ? uiConstraint.getValue().toString() : uiConstraint.getServicePropertyName(); + source.equals(SOURCE) ? uiConstraint.getValue().toString() : uiConstraint.getServicePropertyName(); return Either.right( - componentsUtils.getResponseFormat(ActionStatus.MAPPED_PROPERTY_NOT_FOUND, source, missingProperty)); + componentsUtils.getResponseFormat(ActionStatus.MAPPED_PROPERTY_NOT_FOUND, source, missingProperty)); } private Either validatePropertyData(UIConstraint uiConstraint, @@ -188,48 +214,89 @@ public class NodeFilterValidator { final SchemaDefinition targetSchemaDefinition = targetPropDefinition.getSchema(); if (!sourceSchemaDefinition.equals(targetSchemaDefinition)) { return Either - .right(componentsUtils.getResponseFormat(ActionStatus.SOURCE_TARGET_SCHEMA_MISMATCH, - uiConstraint.getServicePropertyName(), uiConstraint.getValue().toString())); + .right(componentsUtils.getResponseFormat(ActionStatus.SOURCE_TARGET_SCHEMA_MISMATCH, + uiConstraint.getServicePropertyName(), uiConstraint.getValue().toString())); } } return Either.left(Boolean.TRUE); } else { return Either.right(componentsUtils.getResponseFormat(ActionStatus.SOURCE_TARGET_PROPERTY_TYPE_MISMATCH, - uiConstraint.getServicePropertyName(), uiConstraint.getValue().toString())); + uiConstraint.getServicePropertyName(), uiConstraint.getValue().toString())); } } else { LOGGER.debug( - "Null value passed to `validatePropertyData` - sourceSelectedProperty: '{}' - targetComponentInstanceProperty: '{}'", - sourceSelectedProperty, targetComponentInstanceProperty); + "Null value passed to `validatePropertyData` - sourceSelectedProperty: '{}' - targetComponentInstanceProperty: '{}'", + sourceSelectedProperty, targetComponentInstanceProperty); return Either.right(componentsUtils - .getResponseFormat(ActionStatus.GENERAL_ERROR, uiConstraint.getServicePropertyName(), - uiConstraint.getValue().toString())); + .getResponseFormat(ActionStatus.GENERAL_ERROR, uiConstraint.getServicePropertyName(), + uiConstraint.getValue().toString())); } } private Either validateStaticValueAndOperator( - final Component parentComponent, - final String componentInstanceId, final UIConstraint uiConstraint) { + 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 = - parentComponent.getComponentInstancesProperties().get(componentInstanceId).stream() - .filter(property -> uiConstraint.getServicePropertyName().equals(property.getName())) - .findFirst(); + 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())); + uiConstraint.getServicePropertyName())); } if (comparableConstraintsOperators.contains(uiConstraint.getConstraintOperator()) && !comparableTypes.contains( - componentInstanceProperty.get().getType())) { + componentInstanceProperty.get().getType())) { return Either.right(componentsUtils.getResponseFormat(ActionStatus.UNSUPPORTED_OPERATOR_PROVIDED, - uiConstraint.getServicePropertyName(), uiConstraint.getConstraintOperator())); + uiConstraint.getServicePropertyName(), uiConstraint.getConstraintOperator())); } return isValidValueCheck(componentInstanceProperty.get().getType(), String.valueOf(uiConstraint.getValue()), - uiConstraint.getServicePropertyName()); + uiConstraint.getServicePropertyName()); + } + + private Either validateStaticValueAndOperatorOfCapabilityProperties( + final Component parentComponent, final String componentInstanceId, final UIConstraint uiConstraint) { + if (!(Objects.nonNull(uiConstraint) && uiConstraint.getValue() instanceof String)) { + return Either.left(false); + } + Optional optionalComponentInstanceProperty = Optional.empty(); + final Optional optionalComponentInstances = parentComponent.getComponentInstances().stream() + .filter(componentInstance -> componentInstanceId.equalsIgnoreCase(componentInstance.getUniqueId())) + .findFirst(); + if (optionalComponentInstances.isPresent()) { + final Optional> optionalCapabilityDefinitionList = optionalComponentInstances.get() + .getCapabilities().values().stream() + .filter(capabilityDefinitions -> capabilityDefinitions + .stream().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(); + + if (optionalCapabilityDefinitionList.isPresent()) { + optionalComponentInstanceProperty = optionalCapabilityDefinitionList.get().stream().findAny() + .map(capabilityDefinition -> capabilityDefinition.getProperties().get(0)); + } + } + + if (optionalComponentInstanceProperty.isEmpty()) { + return Either.right(componentsUtils.getResponseFormat(ActionStatus.SELECTED_PROPERTY_NOT_PRESENT, + uiConstraint.getServicePropertyName())); + } + if (comparableConstraintsOperators.contains(uiConstraint.getConstraintOperator()) && !comparableTypes.contains( + optionalComponentInstanceProperty.get().getType())) { + return Either.right(componentsUtils.getResponseFormat(ActionStatus.UNSUPPORTED_OPERATOR_PROVIDED, + uiConstraint.getServicePropertyName(), uiConstraint.getConstraintOperator())); + } + + return isValidValueCheck(optionalComponentInstanceProperty.get().getType(), String.valueOf(uiConstraint.getValue()), + uiConstraint.getServicePropertyName()); } private Either isValidValueCheck(String type, String value, String propertyName) { @@ -237,13 +304,13 @@ public class NodeFilterValidator { ToscaPropertyType toscaPropertyType = ToscaPropertyType.isValidType(type); if (Objects.isNull(toscaPropertyType)) { return Either.right( - componentsUtils.getResponseFormat(ActionStatus.UNSUPPORTED_PROPERTY_TYPE, type, propertyName)); + componentsUtils.getResponseFormat(ActionStatus.UNSUPPORTED_PROPERTY_TYPE, type, propertyName)); } if (toscaPropertyType.getValidator().isValid(value, null)) { return Either.left(Boolean.TRUE); } return Either.right( - componentsUtils.getResponseFormat(ActionStatus.UNSUPPORTED_VALUE_PROVIDED, type, propertyName, value)); + componentsUtils.getResponseFormat(ActionStatus.UNSUPPORTED_VALUE_PROVIDED, type, propertyName, value)); } public Either validateComponentFilter(final Component component, 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 5f799211cc..7a6697e77e 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 @@ -22,19 +22,18 @@ package org.openecomp.sdc.be.datamodel.utils; import com.google.common.collect.ImmutableMap; import com.google.common.collect.ImmutableSet; -import org.openecomp.sdc.tosca.datatypes.ToscaFunctions; -import org.openecomp.sdc.be.model.tosca.constraints.ConstraintType; -import org.openecomp.sdc.be.ui.model.UIConstraint; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; -import org.yaml.snakeyaml.Yaml; - import java.util.ArrayList; import java.util.Arrays; import java.util.HashMap; import java.util.List; import java.util.Map; import java.util.Set; +import org.openecomp.sdc.be.model.tosca.constraints.ConstraintType; +import org.openecomp.sdc.be.ui.model.UIConstraint; +import org.openecomp.sdc.tosca.datatypes.ToscaFunctions; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.yaml.snakeyaml.Yaml; public class ConstraintConvertor { @@ -53,7 +52,6 @@ public class ConstraintConvertor { private static Set SUPPORTED_FUNCTIONS = ImmutableSet.of(ToscaFunctions.GET_INPUT.getFunctionName(), ToscaFunctions.GET_PROPERTY.getFunctionName()); - public UIConstraint convert(String inConstraint) { Yaml yamlSource = new Yaml(); UIConstraint uiConstraint = new UIConstraint(); @@ -146,7 +144,6 @@ public class ConstraintConvertor { map2.put(uiConstraint.getConstraintOperator(), map3); } - Yaml yamlSource = new Yaml(); return yamlSource.dump(map1); } catch (NullPointerException ex) { @@ -154,4 +151,41 @@ public class ConstraintConvertor { } return null; } + + public UIConstraint getUiConstraint(final String inConstraint, final UIConstraint uiConstraint) { + final Object constraintObject = new Yaml().load(inConstraint); + if (!(constraintObject instanceof Map)) { + return null; + } + final Map constraintMap = (Map) constraintObject; + final Object capabilityName = constraintMap.keySet().iterator().next(); + uiConstraint.setServicePropertyName(capabilityName.toString()); + Object capabilityProperties = constraintMap.get(capabilityName); + if (!(capabilityProperties instanceof Map)) { + return null; + } + final Map capabilityPropertiesMap = (Map) capabilityProperties; + final Object constraintOperator = capabilityPropertiesMap.keySet().iterator().next(); + final String operator = constraintOperator.toString(); + if (SUPPORTED_CONSTRAINT_LIST.contains(operator)) { + uiConstraint.setConstraintOperator(operator); + } + final Object constraintValue = capabilityPropertiesMap.get(constraintOperator); + if (constraintValue instanceof String || constraintValue instanceof Number || constraintValue instanceof Boolean) { + uiConstraint.setValue(constraintValue); + uiConstraint.setSourceType(STATIC_CONSTRAINT); + 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); + return uiConstraint; + } else if (constraintValue instanceof Map) { + return handleMap(uiConstraint, constraintValue); + } + return null; + + } } 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 2291d8e984..68d8380ed2 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.ArraySchema; 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 java.util.List; import java.util.Optional; import javax.inject.Inject; import javax.inject.Singleton; @@ -41,7 +40,7 @@ import javax.ws.rs.Produces; import javax.ws.rs.core.Context; import javax.ws.rs.core.MediaType; import javax.ws.rs.core.Response; -import org.apache.commons.collections.CollectionUtils; +import org.apache.commons.lang.StringUtils; import org.openecomp.sdc.be.components.impl.ComponentInstanceBusinessLogic; import org.openecomp.sdc.be.components.impl.ComponentNodeFilterBusinessLogic; import org.openecomp.sdc.be.components.impl.ResourceImportManager; @@ -59,20 +58,19 @@ import org.openecomp.sdc.be.impl.ServletUtils; import org.openecomp.sdc.be.model.User; import org.openecomp.sdc.be.tosca.utils.NodeFilterConverter; import org.openecomp.sdc.be.ui.model.UIConstraint; -import org.openecomp.sdc.be.ui.model.UINodeFilter; import org.openecomp.sdc.be.user.UserBusinessLogic; import org.openecomp.sdc.common.api.Constants; import org.slf4j.Logger; import org.slf4j.LoggerFactory; -@Path("/v1/catalog/{componentType}/{componentId}/resourceInstances/{componentInstanceId}/nodeFilter/{constraintType}") +@Path("/v1/catalog/{componentType}/{componentId}/componentInstance/{componentInstanceId}/{constraintType}") @Consumes(MediaType.APPLICATION_JSON) @Produces(MediaType.APPLICATION_JSON) @Singleton public class ComponentNodeFilterServlet extends AbstractValidationsServlet { private static final Logger LOGGER = LoggerFactory.getLogger(ComponentNodeFilterServlet.class); - private static final String START_HANDLE_REQUEST_OF = "Start handle request of {}"; + private static final String START_HANDLE_REQUEST_OF = "Start handle {} request of {}"; private static final String MODIFIER_ID_IS = "modifier id is {}"; private static final String FAILED_TO_PARSE_COMPONENT = "failed to parse component"; @@ -89,6 +87,8 @@ public class ComponentNodeFilterServlet extends AbstractValidationsServlet { private static final String NODE_FILTER_DELETE = "Node Filter Delete"; private static final String DELETE_NODE_FILTER_WITH_AN_ERROR = "delete node filter with an error"; + private static final String INVALID_NODE_FILTER_CONSTRAINT_TYPE = "Invalid value for NodeFilterConstraintType enum {}"; + private final ComponentNodeFilterBusinessLogic componentNodeFilterBusinessLogic; @Inject @@ -105,6 +105,7 @@ public class ComponentNodeFilterServlet extends AbstractValidationsServlet { @POST @Consumes(MediaType.APPLICATION_JSON) @Produces(MediaType.APPLICATION_JSON) + @Path("/nodeFilter") @Operation(description = "Add Component Filter Constraint", method = "POST", summary = "Add Component Filter Constraint", responses = { @ApiResponse(content = @Content(array = @ArraySchema(schema = @Schema(implementation = Response.class)))), @@ -135,32 +136,31 @@ public class ComponentNodeFilterServlet extends AbstractValidationsServlet { try { final Optional convertResponse = componentsUtils .parseToConstraint(constraintData, userModifier, componentTypeEnum); - if (!convertResponse.isPresent()) { + if (convertResponse.isEmpty()) { 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 Optional nodeFilterConstraintType = NodeFilterConstraintType.parse(constraintType); - if (!nodeFilterConstraintType.isPresent()) { + if (nodeFilterConstraintType.isEmpty()) { return buildErrorResponse(getComponentsUtils().getResponseFormat(ActionStatus.INVALID_CONTENT_PARAM, - "Invalid value for NodeFilterConstraintType enum %s", constraintType)); + INVALID_NODE_FILTER_CONSTRAINT_TYPE, constraintType)); } - + final UIConstraint uiConstraint = convertResponse.get(); + final String constraint = new ConstraintConvertor().convert(uiConstraint); final Optional actionResponse = componentNodeFilterBusinessLogic .addNodeFilter(componentId.toLowerCase(), componentInstanceId, NodeFilterConstraintAction.ADD, uiConstraint.getServicePropertyName(), constraint, true, componentTypeEnum, - nodeFilterConstraintType.get()); + nodeFilterConstraintType.get(), + StringUtils.isEmpty(uiConstraint.getCapabilityName()) ? "" : uiConstraint.getCapabilityName()); - if (!actionResponse.isPresent()) { + if (actionResponse.isEmpty()) { LOGGER.error(FAILED_TO_CREATE_NODE_FILTER); return buildErrorResponse(getComponentsUtils().getResponseFormat(ActionStatus.GENERAL_ERROR)); } - final UINodeFilter nodeFilter = new NodeFilterConverter().convertToUi(actionResponse.get()); - return buildOkResponse(getComponentsUtils().getResponseFormat(ActionStatus.OK), nodeFilter); + return buildOkResponse(getComponentsUtils().getResponseFormat(ActionStatus.OK), + new NodeFilterConverter().convertToUi(actionResponse.get())); } catch (final Exception e) { BeEcompErrorManager.getInstance().logBeRestApiGeneralError(NODE_FILTER_CREATION); @@ -172,6 +172,7 @@ public class ComponentNodeFilterServlet extends AbstractValidationsServlet { @PUT @Consumes(MediaType.APPLICATION_JSON) @Produces(MediaType.APPLICATION_JSON) + @Path("/{constraintIndex}/nodeFilter") @Operation(description = "Update Component Filter Constraint", method = "PUT", summary = "Update Component Filter Constraint", responses = { @ApiResponse(content = @Content(array = @ArraySchema(schema = @Schema(implementation = Response.class)))), @@ -191,6 +192,7 @@ public class ComponentNodeFilterServlet extends AbstractValidationsServlet { schema = @Schema(allowableValues = {NodeFilterConstraintType.PROPERTIES_PARAM_NAME, NodeFilterConstraintType.CAPABILITIES_PARAM_NAME})) @PathParam("constraintType") final String constraintType, + @Parameter(description = "Constraint Index") @PathParam("constraintIndex") int index, @Context final HttpServletRequest request, @HeaderParam(value = Constants.USER_ID_HEADER) String userId) { LOGGER.debug(START_HANDLE_REQUEST_OF, request.getMethod(), request.getRequestURI()); @@ -198,26 +200,26 @@ public class ComponentNodeFilterServlet extends AbstractValidationsServlet { final User userModifier = componentNodeFilterBusinessLogic.validateUser(userId); try { - final ComponentTypeEnum componentTypeEnum = ComponentTypeEnum.findByParamName(componentType); - final List uiConstraints = componentsUtils - .validateAndParseConstraint(componentTypeEnum, constraintData, userModifier); - if (CollectionUtils.isEmpty(uiConstraints)) { - LOGGER.error("Failed to Parse Constraint data {} when executing {} ", constraintData, NODE_FILTER_UPDATE); - return buildErrorResponse(componentsUtils.getResponseFormat(ActionStatus.GENERAL_ERROR, - "Failed to parse constraint data", constraintData)); - } - final List constraints = new ConstraintConvertor().convertToList(uiConstraints); - final Optional nodeFilterConstraintType = + final Optional nodeFilterConstraintTypeOptional = NodeFilterConstraintType.parse(constraintType); - if (!nodeFilterConstraintType.isPresent()) { + if (nodeFilterConstraintTypeOptional.isEmpty()) { return buildErrorResponse(getComponentsUtils().getResponseFormat(ActionStatus.INVALID_CONTENT_PARAM, - "Invalid value for NodeFilterConstraintType enum %s", constraintType)); + INVALID_NODE_FILTER_CONSTRAINT_TYPE, constraintType)); } + + final ComponentTypeEnum componentTypeEnum = ComponentTypeEnum.findByParamName(componentType); + final Optional convertResponse = componentsUtils + .parseToConstraint(constraintData, userModifier, componentTypeEnum); + if (convertResponse.isEmpty()) { + LOGGER.error(FAILED_TO_PARSE_COMPONENT); + return buildErrorResponse(getComponentsUtils().getResponseFormat(ActionStatus.GENERAL_ERROR)); + } + final NodeFilterConstraintType nodeFilterConstraintType = nodeFilterConstraintTypeOptional.get(); final Optional actionResponse = componentNodeFilterBusinessLogic - .updateNodeFilter(componentId.toLowerCase(), componentInstanceId, constraints, - true, componentTypeEnum, nodeFilterConstraintType.get()); + .updateNodeFilter(componentId.toLowerCase(), componentInstanceId, convertResponse.get(), + componentTypeEnum, nodeFilterConstraintType, index); - if (!actionResponse.isPresent()) { + if (actionResponse.isEmpty()) { LOGGER.error(FAILED_TO_UPDATE_NODE_FILTER); return buildErrorResponse(getComponentsUtils().getResponseFormat(ActionStatus.GENERAL_ERROR)); } @@ -235,7 +237,7 @@ public class ComponentNodeFilterServlet extends AbstractValidationsServlet { @DELETE @Consumes(MediaType.APPLICATION_JSON) @Produces(MediaType.APPLICATION_JSON) - @Path("/{constraintIndex}") + @Path("{constraintIndex}/nodeFilter") @Operation(description = "Delete Component Filter Constraint", method = "Delete", summary = "Delete Component Filter Constraint", responses = { @ApiResponse(content = @Content(array = @ArraySchema(schema = @Schema(implementation = Response.class)))), @@ -264,16 +266,16 @@ public class ComponentNodeFilterServlet extends AbstractValidationsServlet { try { final Optional nodeFilterConstraintType = NodeFilterConstraintType.parse(constraintType); - if (!nodeFilterConstraintType.isPresent()) { + if (nodeFilterConstraintType.isEmpty()) { return buildErrorResponse(getComponentsUtils().getResponseFormat(ActionStatus.INVALID_CONTENT_PARAM, - "Invalid value for NodeFilterConstraintType enum %s", constraintType)); + INVALID_NODE_FILTER_CONSTRAINT_TYPE, constraintType)); } final Optional actionResponse = componentNodeFilterBusinessLogic .deleteNodeFilter(componentId.toLowerCase(), componentInstanceId, NodeFilterConstraintAction.DELETE, null, index, true, ComponentTypeEnum.findByParamName(componentType), nodeFilterConstraintType.get()); - if (!actionResponse.isPresent()) { + if (actionResponse.isEmpty()) { LOGGER.debug(FAILED_TO_DELETE_NODE_FILTER); return buildErrorResponse(getComponentsUtils().getResponseFormat(ActionStatus.GENERAL_ERROR)); } @@ -285,7 +287,6 @@ public class ComponentNodeFilterServlet extends AbstractValidationsServlet { BeEcompErrorManager.getInstance().logBeRestApiGeneralError(NODE_FILTER_DELETE); LOGGER.debug(DELETE_NODE_FILTER_WITH_AN_ERROR, e); return buildErrorResponse(getComponentsUtils().getResponseFormat(ActionStatus.GENERAL_ERROR)); - } } 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 d1e22f9fa2..3ad50229f4 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 @@ -16,6 +16,7 @@ package org.openecomp.sdc.be.tosca.utils; +import java.util.ArrayList; import java.util.List; import java.util.Map; import java.util.stream.Collectors; @@ -50,15 +51,26 @@ public class NodeFilterConverter { final ListDataDefinition nodeFilterCapabilities = inNodeFilter.getCapabilities(); if (nodeFilterCapabilities != null && !nodeFilterCapabilities.isEmpty()) { - final List capabilitiesConstraint = nodeFilterCapabilities.getListToscaDataDefinition() - .stream() - .map(capabilities -> capabilities.getProperties().getListToscaDataDefinition().iterator().next()) - .map(property -> property.getConstraints().iterator().next()) - .map(constraintConvertor::convert) - .collect(Collectors.toList()); + final List capabilitiesConstraint = new ArrayList<>(); + nodeFilterCapabilities.getListToscaDataDefinition() + .forEach(requirementNodeFilterCapabilityDataDefinition -> + convertCapabilityConstraint(requirementNodeFilterCapabilityDataDefinition, capabilitiesConstraint )); + uiNodeFilter.setCapabilities(capabilitiesConstraint); } return uiNodeFilter; } + + private void convertCapabilityConstraint( + final RequirementNodeFilterCapabilityDataDefinition requirementNodeFilterCapabilityDataDefinition, + final List capabilitiesConstraint) { + + final UIConstraint uiConstraint = new UIConstraint(); + final ConstraintConvertor constraintConvertor = new ConstraintConvertor(); + uiConstraint.setCapabilityName(requirementNodeFilterCapabilityDataDefinition.getName()); + requirementNodeFilterCapabilityDataDefinition.getProperties().getListToscaDataDefinition() + .forEach(property -> capabilitiesConstraint.add(constraintConvertor + .getUiConstraint(property.getConstraints().iterator().next(), uiConstraint))); + } } -- cgit 1.2.3-korg