diff options
25 files changed, 1020 insertions, 369 deletions
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<CINodeFilterDataDefinition, StorageOperationStatus> 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<CINodeFilterDataDefinition> updateNodeFilter(final String componentId, - final String componentInstanceId, - final List<String> constraints, - final boolean shouldLock, - final ComponentTypeEnum componentTypeEnum, - final NodeFilterConstraintType nodeFilterConstraintType) - throws BusinessLogicException { - - final Component component = getComponent(componentId); - - final Either<Boolean, ResponseFormat> 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> 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<CINodeFilterDataDefinition, StorageOperationStatus> 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<CINodeFilterDataDefinition, StorageOperationStatus> updateNodeFilterConstraint( - final String componentId, final String componentInstanceId, final List<String> constraints, - final NodeFilterConstraintType nodeFilterConstraintType, final CINodeFilterDataDefinition nodeFilterDataDefinition) { - - if (NodeFilterConstraintType.PROPERTIES.equals(nodeFilterConstraintType)) { - final List<RequirementNodeFilterPropertyDataDefinition> properties = constraints.stream() - .map(this::getRequirementNodeFilterPropertyDataDefinition).collect(Collectors.toList()); - return nodeFilterOperation.updateProperties(componentId, componentInstanceId, - nodeFilterDataDefinition, properties); - } - final List<RequirementNodeFilterCapabilityDataDefinition> capabilities = constraints.stream() - .map(this::getRequirementNodeFilterCapabilityDataDefinition).collect(Collectors.toList()); - return nodeFilterOperation.updateCapabilities(componentId, componentInstanceId, - nodeFilterDataDefinition, capabilities); - } - private Either<CINodeFilterDataDefinition, StorageOperationStatus> 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<RequirementNodeFilterPropertyDataDefinition> 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<RequirementNodeFilterPropertyDataDefinition> 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> 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<Boolean, ResponseFormat> 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<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()) { + 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<String> comparableTypes = ImmutableSet.of(ToscaPropertyType.STRING.getType(), - ToscaPropertyType.INTEGER.getType(), ToscaPropertyType.FLOAT.getType()); + ToscaPropertyType.INTEGER.getType(), ToscaPropertyType.FLOAT.getType()); public static final Set<String> schemableTypes = - ImmutableSet.of(ToscaPropertyType.MAP.getType(), ToscaPropertyType.LIST.getType()); + ImmutableSet.of(ToscaPropertyType.MAP.getType(), ToscaPropertyType.LIST.getType()); public static final Set<String> 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<Boolean, ResponseFormat> validateFilter(final Component parentComponent, final String componentInstanceId, final List<String> 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<Boolean, ResponseFormat> booleanResponseFormatEither = - validatePropertyConstraint(parentComponent, componentInstanceId, constraint); + validatePropertyConstraint(parentComponent, componentInstanceId, constraint); if (booleanResponseFormatEither.isRight()) { return booleanResponseFormatEither; } } else if (ConstraintConvertor.STATIC_CONSTRAINT.equals(constraint.getSourceType())) { - final Either<Boolean, ResponseFormat> booleanResponseFormatEither = - validateStaticValueAndOperator(parentComponent, componentInstanceId, constraint); + 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; } @@ -122,6 +133,21 @@ public class NodeFilterValidator { return Either.left(true); } + private Either<Boolean, ResponseFormat> isComponentCapabilityPropertyFilterValid(final Component parentComponent, + final String componentInstanceId, + final UIConstraint uiConstraint) { + + return validateStaticValueAndOperatorOfCapabilityProperties(parentComponent, componentInstanceId, uiConstraint); + + } + + private Either<Boolean, ResponseFormat> isComponentPropertyFilterValid(Component parentComponent, + String componentInstanceId, + UIConstraint constraint) { + + return validateStaticValueAndOperator(parentComponent, componentInstanceId, constraint); + } + private Either<Boolean, ResponseFormat> validatePropertyConstraint(final Component parentComponent, final String componentInstanceId, final UIConstraint uiConstraint) { @@ -130,36 +156,36 @@ public class NodeFilterValidator { final List<PropertyDefinition> propertyDefinitions = parentComponent.getProperties(); List<? extends PropertyDefinition> 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<ComponentInstanceProperty> 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<? extends PropertyDefinition> sourceSelectedProperty = sourcePropertyDefinition.stream() - .filter(property -> uiConstraint - .getValue() - .equals(property.getName())) - .findFirst(); + .filter(property -> uiConstraint + .getValue() + .equals(property.getName())) + .findFirst(); final Optional<? extends PropertyDefinition> 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<Boolean, ResponseFormat> 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<Boolean, ResponseFormat> 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> 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<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 Optional<ComponentInstance> optionalComponentInstances = parentComponent.getComponentInstances().stream() + .filter(componentInstance -> componentInstanceId.equalsIgnoreCase(componentInstance.getUniqueId())) + .findFirst(); + if (optionalComponentInstances.isPresent()) { + final Optional<List<CapabilityDefinition>> 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<Boolean, ResponseFormat> 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<Boolean, ResponseFormat> 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<String> 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<UIConstraint> 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 = 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<CINodeFilterDataDefinition> 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<UIConstraint> 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<String> constraints = new ConstraintConvertor().convertToList(uiConstraints); - final Optional<NodeFilterConstraintType> nodeFilterConstraintType = + final Optional<NodeFilterConstraintType> 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<UIConstraint> 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<CINodeFilterDataDefinition> 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 = 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<CINodeFilterDataDefinition> 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<RequirementNodeFilterCapabilityDataDefinition> nodeFilterCapabilities = inNodeFilter.getCapabilities(); if (nodeFilterCapabilities != null && !nodeFilterCapabilities.isEmpty()) { - final List<UIConstraint> 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<UIConstraint> capabilitiesConstraint = new ArrayList<>(); + nodeFilterCapabilities.getListToscaDataDefinition() + .forEach(requirementNodeFilterCapabilityDataDefinition -> + convertCapabilityConstraint(requirementNodeFilterCapabilityDataDefinition, capabilitiesConstraint )); + uiNodeFilter.setCapabilities(capabilitiesConstraint); } return uiNodeFilter; } + + private void convertCapabilityConstraint( + final RequirementNodeFilterCapabilityDataDefinition requirementNodeFilterCapabilityDataDefinition, + final List<UIConstraint> 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))); + } } 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 be9dd1689a..91abd16259 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 @@ -44,6 +44,7 @@ import java.util.Optional; 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; @@ -65,6 +66,7 @@ import org.openecomp.sdc.be.datatypes.enums.ComponentTypeEnum; import org.openecomp.sdc.be.datatypes.enums.NodeFilterConstraintType; 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.ComponentInstance; import org.openecomp.sdc.be.model.ComponentInstanceProperty; import org.openecomp.sdc.be.model.PropertyDefinition; @@ -87,6 +89,7 @@ public class ComponentNodeFilterBusinessLogicTest extends BaseBusinessLogicMock private static final String propertyValue = "resourceTypeValue"; private static final String componentId = "dac65869-dfb4-40d2-aa20-084324659ec1"; private static final String componentInstanceId = "dac65869-dfb4-40d2-aa20-084324659ec1.resource0"; + private static final String capabilityName = "MyCapabilityName"; @InjectMocks private ComponentNodeFilterBusinessLogic componentNodeFilterBusinessLogic; @@ -112,6 +115,7 @@ public class ComponentNodeFilterBusinessLogicTest extends BaseBusinessLogicMock private CINodeFilterDataDefinition ciNodeFilterDataDefinition; private RequirementNodeFilterPropertyDataDefinition requirementNodeFilterPropertyDataDefinition; private String constraint; + private UIConstraint uiConstraint; @BeforeEach public void init() { @@ -257,7 +261,7 @@ public class ComponentNodeFilterBusinessLogicTest extends BaseBusinessLogicMock when(nodeFilterValidator .validateFilter(resource, componentInstanceId, requirementNodeFilterPropertyDataDefinition.getConstraints(), - NodeFilterConstraintAction.ADD)).thenReturn(Either.left(true)); + NodeFilterConstraintAction.ADD, NodeFilterConstraintType.PROPERTIES)).thenReturn(Either.left(true)); when(nodeFilterValidator.validateComponentInstanceExist(resource, componentInstanceId)) .thenReturn(Either.left(true)); when(graphLockOperation.lockComponent(componentId, NodeTypeEnum.Resource)) @@ -270,13 +274,13 @@ public class ComponentNodeFilterBusinessLogicTest extends BaseBusinessLogicMock final Optional<CINodeFilterDataDefinition> result = componentNodeFilterBusinessLogic .addNodeFilter(componentId, componentInstanceId, NodeFilterConstraintAction.ADD, "MyPropertyName", constraint, true, ComponentTypeEnum.RESOURCE, - NodeFilterConstraintType.PROPERTIES); + NodeFilterConstraintType.PROPERTIES, 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); + Collections.singletonList(constraint), NodeFilterConstraintAction.ADD, NodeFilterConstraintType.PROPERTIES); verify(graphLockOperation, times(1)).lockComponent(componentId, NodeTypeEnum.Resource); verify(nodeFilterOperation, times(1)) .addNewProperty(anyString(), anyString(), any(CINodeFilterDataDefinition.class), @@ -292,7 +296,7 @@ public class ComponentNodeFilterBusinessLogicTest extends BaseBusinessLogicMock when(nodeFilterValidator .validateFilter(resource, componentInstanceId, requirementNodeFilterPropertyDataDefinition.getConstraints(), - NodeFilterConstraintAction.ADD)).thenReturn(Either.left(true)); + NodeFilterConstraintAction.ADD, NodeFilterConstraintType.CAPABILITIES)).thenReturn(Either.left(true)); when(nodeFilterValidator.validateComponentInstanceExist(resource, componentInstanceId)) .thenReturn(Either.left(true)); when(graphLockOperation.lockComponent(componentId, NodeTypeEnum.Resource)) @@ -305,13 +309,13 @@ public class ComponentNodeFilterBusinessLogicTest extends BaseBusinessLogicMock final Optional<CINodeFilterDataDefinition> result = componentNodeFilterBusinessLogic .addNodeFilter(componentId, componentInstanceId, NodeFilterConstraintAction.ADD, "MyPropertyName", constraint, true, ComponentTypeEnum.RESOURCE, - NodeFilterConstraintType.CAPABILITIES); + 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); + Collections.singletonList(constraint), NodeFilterConstraintAction.ADD, NodeFilterConstraintType.CAPABILITIES); verify(graphLockOperation, times(1)).lockComponent(componentId, NodeTypeEnum.Resource); verify(nodeFilterOperation, times(1)) .addNewCapabilities(anyString(), anyString(), any(CINodeFilterDataDefinition.class), @@ -327,7 +331,7 @@ public class ComponentNodeFilterBusinessLogicTest extends BaseBusinessLogicMock when(nodeFilterValidator .validateFilter(resource, componentInstanceId, requirementNodeFilterPropertyDataDefinition.getConstraints(), - NodeFilterConstraintAction.ADD)).thenReturn(Either.left(true)); + NodeFilterConstraintAction.ADD, NodeFilterConstraintType.PROPERTIES)).thenReturn(Either.left(true)); when(nodeFilterValidator.validateComponentInstanceExist(resource, componentInstanceId)) .thenReturn(Either.left(true)); when(graphLockOperation.lockComponent(componentId, NodeTypeEnum.Resource)) @@ -339,12 +343,12 @@ public class ComponentNodeFilterBusinessLogicTest extends BaseBusinessLogicMock assertThrows(BusinessLogicException.class, () -> componentNodeFilterBusinessLogic .addNodeFilter(componentId, componentInstanceId, NodeFilterConstraintAction.ADD, "MyPropertyName", constraint, true, ComponentTypeEnum.RESOURCE, - NodeFilterConstraintType.PROPERTIES)); + NodeFilterConstraintType.PROPERTIES, capabilityName)); verify(toscaOperationFacade, times(1)).getToscaElement(componentId); verify(graphLockOperation, times(1)).lockComponent(componentId, NodeTypeEnum.Resource); verify(nodeFilterValidator, times(1)).validateFilter(resource, componentInstanceId, - constraints, NodeFilterConstraintAction.ADD); + constraints, NodeFilterConstraintAction.ADD, NodeFilterConstraintType.PROPERTIES); verify(nodeFilterOperation, times(0)) .addNewProperty(componentId, componentInstanceId, ciNodeFilterDataDefinition, requirementNodeFilterPropertyDataDefinition); @@ -361,7 +365,7 @@ public class ComponentNodeFilterBusinessLogicTest extends BaseBusinessLogicMock assertThrows(BusinessLogicException.class, () -> componentNodeFilterBusinessLogic .addNodeFilter(componentId, componentInstanceId, NodeFilterConstraintAction.ADD, "MyPropertyName", constraint, true, ComponentTypeEnum.RESOURCE, - NodeFilterConstraintType.PROPERTIES)); + NodeFilterConstraintType.PROPERTIES, capabilityName)); } @Test @@ -372,7 +376,7 @@ public class ComponentNodeFilterBusinessLogicTest extends BaseBusinessLogicMock when(nodeFilterValidator.validateComponentInstanceExist(resource, componentInstanceId)) .thenReturn(Either.left(true)); when(nodeFilterValidator.validateFilter(resource, componentInstanceId, singletonList(constraint), - NodeFilterConstraintAction.DELETE)).thenReturn(Either.left(true)); + NodeFilterConstraintAction.DELETE, NodeFilterConstraintType.PROPERTIES)).thenReturn(Either.left(true)); when(graphLockOperation.lockComponent(componentId, NodeTypeEnum.Resource)) .thenReturn(StorageOperationStatus.OK); @@ -396,7 +400,7 @@ public class ComponentNodeFilterBusinessLogicTest extends BaseBusinessLogicMock .validateComponentInstanceExist(resource, componentInstanceId); verify(nodeFilterValidator, times(1)) .validateFilter(resource, componentInstanceId, singletonList(constraint), - NodeFilterConstraintAction.DELETE); + NodeFilterConstraintAction.DELETE, NodeFilterConstraintType.PROPERTIES); verify(nodeFilterOperation, times(1)) .deleteConstraint(componentId, componentInstanceId, ciNodeFilterDataDefinition, 0, NodeFilterConstraintType.PROPERTIES); @@ -411,7 +415,7 @@ public class ComponentNodeFilterBusinessLogicTest extends BaseBusinessLogicMock when(nodeFilterValidator.validateComponentInstanceExist(resource, componentInstanceId)) .thenReturn(Either.left(true)); when(nodeFilterValidator.validateFilter(resource, componentInstanceId, singletonList(constraint), - NodeFilterConstraintAction.DELETE)).thenReturn(Either.left(true)); + NodeFilterConstraintAction.DELETE, NodeFilterConstraintType.PROPERTIES)).thenReturn(Either.left(true)); when(graphLockOperation.lockComponent(componentId, NodeTypeEnum.Resource)) .thenReturn(StorageOperationStatus.OK); @@ -431,7 +435,7 @@ public class ComponentNodeFilterBusinessLogicTest extends BaseBusinessLogicMock verify(graphLockOperation, times(1)).lockComponent(componentId, NodeTypeEnum.Resource); verify(nodeFilterValidator, times(1)) .validateFilter(resource, componentInstanceId, singletonList(constraint), - NodeFilterConstraintAction.DELETE); + NodeFilterConstraintAction.DELETE, NodeFilterConstraintType.PROPERTIES); verify(nodeFilterValidator, times(1)) .validateComponentInstanceExist(resource, componentInstanceId); verify(graphLockOperation, times(1)).unlockComponent(componentId, NodeTypeEnum.Resource); @@ -443,7 +447,7 @@ public class ComponentNodeFilterBusinessLogicTest extends BaseBusinessLogicMock when(nodeFilterValidator.validateComponentInstanceExist(resource, componentInstanceId)) .thenReturn(Either.left(true)); when(nodeFilterValidator.validateFilter(resource, componentInstanceId, singletonList(constraint), - NodeFilterConstraintAction.DELETE)).thenReturn(Either.left(true)); + NodeFilterConstraintAction.DELETE, NodeFilterConstraintType.PROPERTIES)).thenReturn(Either.left(true)); assertThrows(BusinessLogicException.class, () -> componentNodeFilterBusinessLogic .deleteNodeFilter(componentId, componentInstanceId, NodeFilterConstraintAction.DELETE, constraint, @@ -452,7 +456,7 @@ public class ComponentNodeFilterBusinessLogicTest extends BaseBusinessLogicMock verify(toscaOperationFacade, times(1)).getToscaElement(componentId); verify(nodeFilterValidator, times(1)) .validateFilter(resource, componentInstanceId, singletonList(constraint), - NodeFilterConstraintAction.DELETE); + NodeFilterConstraintAction.DELETE, NodeFilterConstraintType.PROPERTIES); verify(nodeFilterValidator, times(1)) .validateComponentInstanceExist(resource, componentInstanceId); } @@ -462,31 +466,31 @@ public class ComponentNodeFilterBusinessLogicTest extends BaseBusinessLogicMock componentInstance.setNodeFilter(ciNodeFilterDataDefinition); when(toscaOperationFacade.getToscaElement(componentId)).thenReturn(Either.left(resource)); - when(nodeFilterValidator.validateFilter(resource, componentInstanceId, - Collections.singletonList(constraint), NodeFilterConstraintAction.UPDATE)).thenReturn(Either.left(true)); + 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))).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(graphLockOperation.unlockComponent(componentId, NodeTypeEnum.Resource)) .thenReturn(StorageOperationStatus.OK); - when(nodeFilterOperation.updateCapabilities(anyString(), anyString(), - any(CINodeFilterDataDefinition.class), anyList())).thenReturn(Either.left(ciNodeFilterDataDefinition)); - - final List<String> constraints = requirementNodeFilterPropertyDataDefinition.getConstraints(); final Optional<CINodeFilterDataDefinition> updateNodeFilterResult = componentNodeFilterBusinessLogic - .updateNodeFilter(componentId, componentInstanceId, constraints, true, ComponentTypeEnum.RESOURCE, - NodeFilterConstraintType.CAPABILITIES); + .updateNodeFilter(componentId, componentInstanceId, uiConstraint, ComponentTypeEnum.RESOURCE, + NodeFilterConstraintType.PROPERTIES, 0); assertThat(updateNodeFilterResult).isPresent(); assertThat(updateNodeFilterResult.get().getProperties().getListToscaDataDefinition()).hasSize(1); - - verify(toscaOperationFacade, times(1)).getToscaElement(componentId); - verify(graphLockOperation, times(1)).lockComponent(componentId, NodeTypeEnum.Resource); - verify(nodeFilterValidator, times(1)).validateFilter(resource, componentInstanceId, - constraints, NodeFilterConstraintAction.UPDATE); - verify(graphLockOperation, times(1)).unlockComponent(componentId, NodeTypeEnum.Resource); - verify(nodeFilterOperation, times(1)) - .updateCapabilities(anyString(), anyString(), any(CINodeFilterDataDefinition.class), anyList()); } @Test @@ -494,37 +498,45 @@ public class ComponentNodeFilterBusinessLogicTest extends BaseBusinessLogicMock componentInstance.setNodeFilter(ciNodeFilterDataDefinition); when(toscaOperationFacade.getToscaElement(componentId)).thenReturn(Either.left(resource)); - when(nodeFilterValidator.validateFilter(resource, componentInstanceId, - Collections.singletonList(constraint), NodeFilterConstraintAction.UPDATE)).thenReturn(Either.left(true)); + 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))).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.right(StorageOperationStatus.GENERAL_ERROR)); + when(graphLockOperation.unlockComponent(componentId, NodeTypeEnum.Resource)) .thenReturn(StorageOperationStatus.OK); - final List<String> constraints = requirementNodeFilterPropertyDataDefinition.getConstraints(); assertThrows(BusinessLogicException.class, () -> componentNodeFilterBusinessLogic - .updateNodeFilter(componentId, componentInstanceId, constraints, true, ComponentTypeEnum.RESOURCE, - NodeFilterConstraintType.PROPERTIES)); - - verify(toscaOperationFacade, times(1)).getToscaElement(componentId); - verify(nodeFilterValidator, times(1)).validateFilter(resource, componentInstanceId, - constraints, NodeFilterConstraintAction.UPDATE); + .updateNodeFilter(componentId, componentInstanceId, uiConstraint, ComponentTypeEnum.RESOURCE, + NodeFilterConstraintType.PROPERTIES, 0)); } @Test public void updateNodeFilterFailValidationTest() { - final List<String> constraints = requirementNodeFilterPropertyDataDefinition.getConstraints(); when(toscaOperationFacade.getToscaElement(componentId)).thenReturn(Either.left(resource)); - when(nodeFilterValidator.validateFilter(resource, componentInstanceId, - constraints, NodeFilterConstraintAction.UPDATE)).thenReturn(Either.left(true)); + 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))).thenReturn(Either.left(true)); assertThrows(BusinessLogicException.class, () -> componentNodeFilterBusinessLogic - .updateNodeFilter(componentId, componentInstanceId, constraints, true, ComponentTypeEnum.RESOURCE, - NodeFilterConstraintType.PROPERTIES)); + .updateNodeFilter(componentId, componentInstanceId, uiConstraint, ComponentTypeEnum.RESOURCE, + NodeFilterConstraintType.PROPERTIES, 0)); verify(toscaOperationFacade, times(1)).getToscaElement(componentId); - verify(nodeFilterValidator, times(1)).validateFilter(resource, componentInstanceId, - constraints, NodeFilterConstraintAction.UPDATE); } @Test @@ -555,8 +567,7 @@ public class ComponentNodeFilterBusinessLogicTest extends BaseBusinessLogicMock componentInstance.setDirectives(ConfigurationManager.getConfigurationManager().getConfiguration() .getDirectives()); - final UIConstraint uiConstraint = - new UIConstraint(servicePropertyName, constraintOperator, sourceType, sourceName, propertyValue); + uiConstraint = new UIConstraint(servicePropertyName, constraintOperator, sourceType, sourceName, propertyValue); constraint = new ConstraintConvertor().convert(uiConstraint); requirementNodeFilterPropertyDataDefinition = new RequirementNodeFilterPropertyDataDefinition(); 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 index 83a968c756..82dde5e396 100644 --- 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 @@ -31,6 +31,7 @@ import org.openecomp.sdc.be.components.impl.utils.NodeFilterConstraintAction; 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; @@ -74,7 +75,7 @@ public class NodeFilterValidationTest { Either<Boolean, ResponseFormat> either = nodeFilterValidator.validateFilter(service, INNER_SERVICE, Collections.singletonList(UI_CONSTRAINT_STATIC.replace(VALUE, "true")), - NodeFilterConstraintAction.ADD); + NodeFilterConstraintAction.ADD, NodeFilterConstraintType.PROPERTIES); Assert.assertFalse(either.isLeft()); } @@ -86,7 +87,7 @@ public class NodeFilterValidationTest { nodeFilterValidator.validateFilter(service, INNER_SERVICE, Collections.singletonList(UI_CONSTRAINT_STATIC.replace(VALUE, "true") .replace("equal", "greater_than")), - NodeFilterConstraintAction.ADD); + NodeFilterConstraintAction.ADD, NodeFilterConstraintType.PROPERTIES); Assert.assertFalse(either.isLeft()); } @@ -97,7 +98,7 @@ public class NodeFilterValidationTest { Either<Boolean, ResponseFormat> either = nodeFilterValidator.validateFilter(service, INNER_SERVICE, Collections.singletonList(UI_CONSTRAINT_STATIC.replace(VALUE, "trues")), - NodeFilterConstraintAction.ADD); + NodeFilterConstraintAction.ADD, NodeFilterConstraintType.PROPERTIES); Assert.assertFalse(either.isLeft()); } @@ -109,7 +110,7 @@ public class NodeFilterValidationTest { nodeFilterValidator.validateFilter(service, INNER_SERVICE, Collections.singletonList(UI_CONSTRAINT_STATIC.replace(VALUE, "true") .replace("equal", "greater_than")), - NodeFilterConstraintAction.ADD); + NodeFilterConstraintAction.ADD, NodeFilterConstraintType.PROPERTIES); Assert.assertTrue(either.isLeft()); } @@ -120,7 +121,7 @@ public class NodeFilterValidationTest { Either<Boolean, ResponseFormat> either = nodeFilterValidator.validateFilter(service, INNER_SERVICE, Collections.singletonList(UI_CONSTRAINT_STATIC.replace(VALUE, "1")), - NodeFilterConstraintAction.ADD); + NodeFilterConstraintAction.ADD, NodeFilterConstraintType.PROPERTIES); Assert.assertTrue(either.isLeft()); } @@ -135,7 +136,7 @@ public class NodeFilterValidationTest { Either<Boolean, ResponseFormat> either = nodeFilterValidator.validateFilter(service, INNER_SERVICE, Collections.singletonList(UI_CONSTRAINT_STATIC.replace(VALUE, "1.0")), - NodeFilterConstraintAction.ADD); + NodeFilterConstraintAction.ADD, NodeFilterConstraintType.PROPERTIES); Assert.assertTrue(either.isRight()); } @@ -146,7 +147,7 @@ public class NodeFilterValidationTest { Either<Boolean, ResponseFormat> either = nodeFilterValidator.validateFilter(service, INNER_SERVICE, Collections.singletonList(UI_CONSTRAINT_STATIC.replace(VALUE, "1.0")), - NodeFilterConstraintAction.ADD); + NodeFilterConstraintAction.ADD, NodeFilterConstraintType.PROPERTIES); Assert.assertTrue(either.isLeft()); } @@ -160,7 +161,8 @@ public class NodeFilterValidationTest { Either<Boolean, ResponseFormat> either = nodeFilterValidator.validateFilter(service, INNER_SERVICE, - Collections.singletonList(UI_CONSTRAINT_STATIC), NodeFilterConstraintAction.ADD); + Collections.singletonList(UI_CONSTRAINT_STATIC), NodeFilterConstraintAction.ADD, + NodeFilterConstraintType.PROPERTIES); Assert.assertTrue(either.isRight()); } @@ -170,7 +172,8 @@ public class NodeFilterValidationTest { Service service = createService(STRING_TYPE); Either<Boolean, ResponseFormat> either = nodeFilterValidator.validateFilter(service, INNER_SERVICE, - Collections.singletonList(UI_CONSTRAINT_STATIC), NodeFilterConstraintAction.ADD); + Collections.singletonList(UI_CONSTRAINT_STATIC), NodeFilterConstraintAction.ADD, + NodeFilterConstraintType.PROPERTIES); Assert.assertTrue(either.isLeft()); } @@ -180,7 +183,8 @@ public class NodeFilterValidationTest { 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); + + " equal: { get_property :[component2, Prop1]}\n"), NodeFilterConstraintAction.ADD, + NodeFilterConstraintType.PROPERTIES); Assert.assertTrue(either.isLeft()); } @@ -190,7 +194,8 @@ public class NodeFilterValidationTest { Service service = createService(STRING_TYPE); Either<Boolean, ResponseFormat> either = nodeFilterValidator.validateFilter(service, COMPONENT1_ID, Collections.singletonList("Prop1:\n" - + " equal: { get_property : [parentservice, Prop1]}\n"), NodeFilterConstraintAction.ADD); + + " equal: { get_property : [parentservice, Prop1]}\n"), NodeFilterConstraintAction.ADD, + NodeFilterConstraintType.PROPERTIES); Assert.assertTrue(either.isLeft()); } @@ -202,7 +207,8 @@ public class NodeFilterValidationTest { Either<Boolean, ResponseFormat> either = nodeFilterValidator.validateFilter(service, COMPONENT1_ID, Collections.singletonList("Prop1:\n" - + " equal: { get_property : [component2, Prop1]}\n"), NodeFilterConstraintAction.ADD); + + " equal: { get_property : [component2, Prop1]}\n"), NodeFilterConstraintAction.ADD, + NodeFilterConstraintType.PROPERTIES); Assert.assertFalse(either.isLeft()); } @@ -214,7 +220,8 @@ public class NodeFilterValidationTest { Either<Boolean, ResponseFormat> either = nodeFilterValidator.validateFilter(service, COMPONENT1_ID, Collections.singletonList("Prop1:\n" - + " equal: { get_property : [parentservice, Prop1]}\n"), NodeFilterConstraintAction.ADD); + + " equal: { get_property : [parentservice, Prop1]}\n"), NodeFilterConstraintAction.ADD, + NodeFilterConstraintType.PROPERTIES); Assert.assertFalse(either.isLeft()); } @@ -226,7 +233,8 @@ public class NodeFilterValidationTest { Either<Boolean, ResponseFormat> either = nodeFilterValidator.validateFilter(service, COMPONENT1_ID, Collections.singletonList("Prop1:\n" - + " equal: { get_property : [parentservice, Prop1]}\n"), NodeFilterConstraintAction.ADD); + + " equal: { get_property : [parentservice, Prop1]}\n"), NodeFilterConstraintAction.ADD, + NodeFilterConstraintType.PROPERTIES); Assert.assertFalse(either.isLeft()); } @@ -238,7 +246,8 @@ public class NodeFilterValidationTest { Either<Boolean, ResponseFormat> either = nodeFilterValidator.validateFilter(service, COMPONENT1_ID, Collections.singletonList("Prop1:\n" - + " equal: { get_property : [parentservice, Prop1]}\n"), NodeFilterConstraintAction.ADD); + + " equal: { get_property : [parentservice, Prop1]}\n"), NodeFilterConstraintAction.ADD, + NodeFilterConstraintType.PROPERTIES); Assert.assertFalse(either.isLeft()); } @@ -250,7 +259,8 @@ public class NodeFilterValidationTest { Either<Boolean, ResponseFormat> either = nodeFilterValidator.validateFilter(service, COMPONENT1_ID, Collections.singletonList("Prop1:\n" - + " equal: { get_property : [parentservice, Prop1]}\n"), NodeFilterConstraintAction.ADD); + + " equal: { get_property : [parentservice, Prop1]}\n"), NodeFilterConstraintAction.ADD, + NodeFilterConstraintType.PROPERTIES); Assert.assertFalse(either.isLeft()); } 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 a745f41ec0..4109f6222c 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 @@ -24,7 +24,6 @@ import static org.junit.Assert.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.nullable; import static org.mockito.Mockito.mock; @@ -98,6 +97,7 @@ public class ComponentNodeFilterServletTest extends JerseyTest { private static final String componentId = "dac65869-dfb4-40d2-aa20-084324659ec1"; private static final String componentInstance = "dac65869-dfb4-40d2-aa20-084324659ec1.resource0"; private static final String componentType = "resources"; + private static final String capabilityName = "MyCapabilityName"; private static HttpServletRequest request; private static HttpSession session; @@ -146,7 +146,7 @@ public class ComponentNodeFilterServletTest extends JerseyTest { @Test public void addNodeFilterPropertiesSuccessTest() throws BusinessLogicException, JsonProcessingException { initComponentData(); - final String pathFormat = "/v1/catalog/%s/%s/resourceInstances/%s/nodeFilter/%s"; + final String pathFormat = "/v1/catalog/%s/%s/componentInstance/%s/%s/nodeFilter"; final String path = String.format(pathFormat, componentType, componentId, componentInstance, NodeFilterConstraintType.PROPERTIES_PARAM_NAME); @@ -172,7 +172,7 @@ public class ComponentNodeFilterServletTest extends JerseyTest { when(componentNodeFilterBusinessLogic .addNodeFilter(componentId, componentInstance, NodeFilterConstraintAction.ADD, uiConstraint.getServicePropertyName(), constraint, true, ComponentTypeEnum.RESOURCE, - NodeFilterConstraintType.PROPERTIES)) + NodeFilterConstraintType.PROPERTIES, "")) .thenReturn(Optional.of(ciNodeFilterDataDefinition)); final Response response = target() @@ -184,7 +184,7 @@ public class ComponentNodeFilterServletTest extends JerseyTest { verify(componentNodeFilterBusinessLogic, times(1)) .addNodeFilter(anyString(), anyString(), ArgumentMatchers.any(NodeFilterConstraintAction.class), anyString(), anyString(), anyBoolean(), ArgumentMatchers.any(ComponentTypeEnum.class), - ArgumentMatchers.any(NodeFilterConstraintType.class)); + ArgumentMatchers.any(NodeFilterConstraintType.class), anyString()); assertThat(response.getStatus()).isEqualTo(HttpStatus.OK_200); } @@ -192,10 +192,11 @@ public class ComponentNodeFilterServletTest extends JerseyTest { @Test public void addNodeFilterCapabilitiesSuccessTest() throws BusinessLogicException, JsonProcessingException { initComponentData(); - final String pathFormat = "/v1/catalog/%s/%s/resourceInstances/%s/nodeFilter/%s"; + final String pathFormat = "/v1/catalog/%s/%s/componentInstance/%s/%s/nodeFilter"; final String path = String.format(pathFormat, componentType, componentId, componentInstance, NodeFilterConstraintType.CAPABILITIES_PARAM_NAME); + final UIConstraint uiConstraint1 = uiConstraint; when(userValidations.validateUserExists(user)).thenReturn(user); when(componentNodeFilterBusinessLogic.validateUser(USER_ID)).thenReturn(user); when(responseFormat.getStatus()).thenReturn(HttpStatus.OK_200); @@ -203,11 +204,12 @@ public class ComponentNodeFilterServletTest extends JerseyTest { when(componentsUtils.parseToConstraint(anyString(), any(User.class),ArgumentMatchers.any(ComponentTypeEnum.class))) .thenReturn(Optional.of(uiConstraint)); + uiConstraint1.setCapabilityName(capabilityName); assertThat(ciNodeFilterDataDefinition.getProperties().getListToscaDataDefinition()).hasSize(1); when(componentNodeFilterBusinessLogic .addNodeFilter(componentId, componentInstance, NodeFilterConstraintAction.ADD, - uiConstraint.getServicePropertyName(), constraint, true, ComponentTypeEnum.RESOURCE, - NodeFilterConstraintType.CAPABILITIES)) + uiConstraint1.getServicePropertyName(), constraint, true, ComponentTypeEnum.RESOURCE, + NodeFilterConstraintType.CAPABILITIES, capabilityName)) .thenReturn(Optional.of(ciNodeFilterDataDefinition)); final Response response = target() @@ -219,7 +221,7 @@ public class ComponentNodeFilterServletTest extends JerseyTest { verify(componentNodeFilterBusinessLogic, times(1)) .addNodeFilter(anyString(), anyString(), ArgumentMatchers.any(NodeFilterConstraintAction.class), anyString(), anyString(), anyBoolean(), ArgumentMatchers.any(ComponentTypeEnum.class), - ArgumentMatchers.any(NodeFilterConstraintType.class)); + ArgumentMatchers.any(NodeFilterConstraintType.class), anyString()); assertThat(response.getStatus()).isEqualTo(HttpStatus.OK_200); } @@ -227,7 +229,7 @@ public class ComponentNodeFilterServletTest extends JerseyTest { @Test public void addNodeFilterFailTest() throws BusinessLogicException, JsonProcessingException { initComponentData(); - final String pathFormat = "/v1/catalog/%s/%s/resourceInstances/%s/nodeFilter/%s"; + final String pathFormat = "/v1/catalog/%s/%s/componentInstance/%s/%s/nodeFilter"; final String path = String.format(pathFormat, componentType, componentId, componentInstance, NodeFilterConstraintType.PROPERTIES_PARAM_NAME); @@ -243,7 +245,7 @@ public class ComponentNodeFilterServletTest extends JerseyTest { when(componentNodeFilterBusinessLogic .addNodeFilter(componentId, componentInstance, NodeFilterConstraintAction.ADD, uiConstraint.getServicePropertyName(), constraint, true, ComponentTypeEnum.RESOURCE, - NodeFilterConstraintType.PROPERTIES)) + NodeFilterConstraintType.PROPERTIES, "")) .thenReturn(Optional.empty()); final Response response = target() @@ -258,7 +260,7 @@ public class ComponentNodeFilterServletTest extends JerseyTest { @Test public void addNodeFilterFailConstraintParseTest() throws JsonProcessingException { initComponentData(); - final String pathFormat = "/v1/catalog/%s/%s/resourceInstances/%s/nodeFilter/%s"; + final String pathFormat = "/v1/catalog/%s/%s/componentInstance/%s/%s/nodeFilter"; final String path = String.format(pathFormat, componentType, componentId, componentInstance, NodeFilterConstraintType.PROPERTIES_PARAM_NAME); when(userValidations.validateUserExists(user)).thenReturn(user); @@ -282,9 +284,9 @@ public class ComponentNodeFilterServletTest extends JerseyTest { } @Test - public void addNodeFilterFailConvertTest() throws JsonProcessingException, BusinessLogicException { + public void addNodeFilterFailConvertTest() throws JsonProcessingException { initComponentData(); - final String pathFormat = "/v1/catalog/%s/%s/resourceInstances/%s/nodeFilter/%s"; + final String pathFormat = "/v1/catalog/%s/%s/componentInstance/%s/%s/nodeFilter"; final String path = String.format(pathFormat, componentType, componentId, componentInstance, NodeFilterConstraintType.PROPERTIES.getType()); @@ -311,9 +313,9 @@ public class ComponentNodeFilterServletTest extends JerseyTest { @Test public void updateNodeFilterPropertiesSuccessTest() throws BusinessLogicException, JsonProcessingException { initComponentData(); - final String pathFormat = "/v1/catalog/%s/%s/resourceInstances/%s/nodeFilter/%s"; + final String pathFormat = "/v1/catalog/%s/%s/componentInstance/%s/%s/%s/nodeFilter"; final String path = String.format(pathFormat, componentType, componentId, componentInstance, - NodeFilterConstraintType.PROPERTIES_PARAM_NAME); + NodeFilterConstraintType.PROPERTIES_PARAM_NAME, 0); when(userValidations.validateUserExists(user)).thenReturn(user); when(componentNodeFilterBusinessLogic.validateUser(USER_ID)).thenReturn(user); @@ -327,9 +329,8 @@ public class ComponentNodeFilterServletTest extends JerseyTest { .thenReturn(Either.left(Arrays.asList(new ObjectMapper().convertValue(uiConstraint, Map.class)))); when(componentNodeFilterBusinessLogic - .updateNodeFilter(componentId, componentInstance, Collections.singletonList(constraint), - true, ComponentTypeEnum.RESOURCE, NodeFilterConstraintType.PROPERTIES)) - .thenReturn(Optional.of(ciNodeFilterDataDefinition)); + .updateNodeFilter(componentId, componentInstance, uiConstraint, ComponentTypeEnum.RESOURCE, + NodeFilterConstraintType.PROPERTIES, 0)).thenReturn(Optional.of(ciNodeFilterDataDefinition)); final Response response = target() .path(path) .request(MediaType.APPLICATION_JSON) @@ -337,8 +338,9 @@ public class ComponentNodeFilterServletTest extends JerseyTest { .put(Entity.entity(inputJson, MediaType.APPLICATION_JSON)); verify(componentNodeFilterBusinessLogic, times(1)) - .updateNodeFilter(anyString(), anyString(), anyList(), anyBoolean(), - ArgumentMatchers.any(ComponentTypeEnum.class), ArgumentMatchers.any(NodeFilterConstraintType.class)); + .updateNodeFilter(anyString(), anyString(), ArgumentMatchers.any(UIConstraint.class), + ArgumentMatchers.any(ComponentTypeEnum.class), ArgumentMatchers.any(NodeFilterConstraintType.class), + anyInt()); assertThat(response.getStatus()).isEqualTo(HttpStatus.OK_200); } @@ -346,13 +348,16 @@ public class ComponentNodeFilterServletTest extends JerseyTest { @Test public void updateNodeFilterCapabilitiesSuccessTest() throws BusinessLogicException, JsonProcessingException { initComponentData(); - final String pathFormat = "/v1/catalog/%s/%s/resourceInstances/%s/nodeFilter/%s"; + final String pathFormat = "/v1/catalog/%s/%s/componentInstance/%s/%s/%s/nodeFilter"; final String path = String.format(pathFormat, componentType, componentId, componentInstance, - NodeFilterConstraintType.CAPABILITIES_PARAM_NAME); + NodeFilterConstraintType.CAPABILITIES_PARAM_NAME, 0); when(userValidations.validateUserExists(user)).thenReturn(user); when(componentNodeFilterBusinessLogic.validateUser(USER_ID)).thenReturn(user); + when(componentsUtils.parseToConstraint(anyString(), any(User.class), ArgumentMatchers.any(ComponentTypeEnum.class))) + .thenReturn(Optional.of(uiConstraint)); + when(responseFormat.getStatus()).thenReturn(HttpStatus.OK_200); when(componentsUtils.getResponseFormat(ActionStatus.OK)).thenReturn(responseFormat); @@ -364,10 +369,22 @@ public class ComponentNodeFilterServletTest extends JerseyTest { nullable(AuditingActionEnum.class), nullable(ComponentTypeEnum.class))) .thenReturn(Either.left(Arrays.asList(new ObjectMapper().convertValue(uiConstraint, Map.class)))); + when(componentNodeFilterBusinessLogic.deleteNodeFilter(componentId, componentInstance, + NodeFilterConstraintAction.DELETE, null, 0, true, ComponentTypeEnum.RESOURCE, + NodeFilterConstraintType.PROPERTIES)) + .thenReturn(Optional.of(ciNodeFilterDataDefinition)); + when(componentNodeFilterBusinessLogic - .updateNodeFilter(componentId, componentInstance, Collections.singletonList(constraint), - true, ComponentTypeEnum.RESOURCE, NodeFilterConstraintType.CAPABILITIES)) + .addNodeFilter(componentId, componentInstance, NodeFilterConstraintAction.ADD, + uiConstraint.getServicePropertyName(), constraint, true, ComponentTypeEnum.RESOURCE, + NodeFilterConstraintType.PROPERTIES, "")) .thenReturn(Optional.of(ciNodeFilterDataDefinition)); + + when(componentNodeFilterBusinessLogic + .updateNodeFilter(componentId, componentInstance, uiConstraint, + ComponentTypeEnum.RESOURCE, NodeFilterConstraintType.CAPABILITIES, 0)) + .thenReturn(Optional.of(ciNodeFilterDataDefinition)); + final Response response = target() .path(path) .request(MediaType.APPLICATION_JSON) @@ -375,8 +392,9 @@ public class ComponentNodeFilterServletTest extends JerseyTest { .put(Entity.entity(inputJson, MediaType.APPLICATION_JSON)); verify(componentNodeFilterBusinessLogic, times(1)) - .updateNodeFilter(anyString(), anyString(), anyList(), anyBoolean(), - ArgumentMatchers.any(ComponentTypeEnum.class), ArgumentMatchers.any(NodeFilterConstraintType.class)); + .updateNodeFilter(anyString(), anyString(), ArgumentMatchers.any(UIConstraint.class), + ArgumentMatchers.any(ComponentTypeEnum.class), ArgumentMatchers.any(NodeFilterConstraintType.class), + anyInt()); assertThat(response.getStatus()).isEqualTo(HttpStatus.OK_200); } @@ -384,9 +402,9 @@ public class ComponentNodeFilterServletTest extends JerseyTest { @Test public void updateNodeFilterFailTest() throws BusinessLogicException, JsonProcessingException { initComponentData(); - final String pathFormat = "/v1/catalog/%s/%s/resourceInstances/%s/nodeFilter/%s"; + final String pathFormat = "/v1/catalog/%s/%s/componentInstance/%s/%s/%s/nodeFilter"; final String path = String.format(pathFormat, componentType, componentId, componentInstance, - NodeFilterConstraintType.PROPERTIES_PARAM_NAME); + NodeFilterConstraintType.PROPERTIES_PARAM_NAME, 0); when(userValidations.validateUserExists(user)).thenReturn(user); when(componentNodeFilterBusinessLogic.validateUser(USER_ID)).thenReturn(user); @@ -397,8 +415,8 @@ public class ComponentNodeFilterServletTest extends JerseyTest { .thenReturn(Collections.singletonList(uiConstraint)); when(componentNodeFilterBusinessLogic - .updateNodeFilter(componentId, componentInstance, Collections.singletonList(constraint), - true, ComponentTypeEnum.RESOURCE, NodeFilterConstraintType.PROPERTIES)) + .updateNodeFilter(componentId, componentInstance, uiConstraint, + ComponentTypeEnum.RESOURCE, NodeFilterConstraintType.PROPERTIES, 0)) .thenReturn(Optional.empty()); final Response response = target() .path(path) @@ -407,9 +425,9 @@ public class ComponentNodeFilterServletTest extends JerseyTest { .put(Entity.entity(inputJson, MediaType.APPLICATION_JSON)); verify(componentNodeFilterBusinessLogic, times(1)) - .updateNodeFilter(anyString(), anyString(), anyList(), anyBoolean(), - ArgumentMatchers.any(ComponentTypeEnum.class), ArgumentMatchers.any(NodeFilterConstraintType.class)); - + .updateNodeFilter(anyString(), anyString(), ArgumentMatchers.any(UIConstraint.class), + ArgumentMatchers.any(ComponentTypeEnum.class), ArgumentMatchers.any(NodeFilterConstraintType.class), + anyInt()); assertThat(response.getStatus()).isEqualTo(HttpStatus.INTERNAL_SERVER_ERROR_500); } @@ -417,9 +435,9 @@ public class ComponentNodeFilterServletTest extends JerseyTest { @Test public void updateNodeFilterFailConstraintParseTest() throws JsonProcessingException { initComponentData(); - final String pathFormat = "/v1/catalog/%s/%s/resourceInstances/%s/nodeFilter/%s"; + final String pathFormat = "/v1/catalog/%s/%s/componentInstance/%s/%s/%s/nodeFilter"; final String path = String.format(pathFormat, componentType, componentId, componentInstance, - NodeFilterConstraintType.PROPERTIES_PARAM_NAME); + NodeFilterConstraintType.PROPERTIES_PARAM_NAME, 0); when(userValidations.validateUserExists(user)).thenReturn(user); when(componentNodeFilterBusinessLogic.validateUser(USER_ID)).thenReturn(user); @@ -440,9 +458,9 @@ public class ComponentNodeFilterServletTest extends JerseyTest { @Test public void updateNodeFilterFailConvertTest() throws JsonProcessingException { initComponentData(); - final String pathFormat = "/v1/catalog/%s/%s/resourceInstances/%s/nodeFilter/%s"; + final String pathFormat = "/v1/catalog/%s/%s/componentInstance/%s/%s/%s/nodeFilter"; final String path = String.format(pathFormat, componentType, componentId, componentInstance, - NodeFilterConstraintType.PROPERTIES_PARAM_NAME); + NodeFilterConstraintType.PROPERTIES_PARAM_NAME, 0); when(userValidations.validateUserExists(user)).thenReturn(user); when(componentNodeFilterBusinessLogic.validateUser(USER_ID)).thenReturn(user); @@ -465,7 +483,7 @@ public class ComponentNodeFilterServletTest extends JerseyTest { @Test public void deleteNodeFilterSuccessTest() throws BusinessLogicException, JsonProcessingException { initComponentData(); - final String pathFormat = "/v1/catalog/%s/%s/resourceInstances/%s/nodeFilter/%s/%s"; + final String pathFormat = "/v1/catalog/%s/%s/componentInstance/%s/%s/%s/nodeFilter"; final String path = String.format(pathFormat, componentType, componentId, componentInstance, NodeFilterConstraintType.PROPERTIES_PARAM_NAME, 0); @@ -497,9 +515,9 @@ public class ComponentNodeFilterServletTest extends JerseyTest { @Test public void deleteNodeFilterFailTest() { - final String pathFormat = "/v1/catalog/%s/%s/resourceInstances/%s/nodeFilter/%s/%s"; + final String pathFormat = "/v1/catalog/%s/%s/componentInstance/%s/%s/%s/nodeFilter"; final String path = String.format(pathFormat, componentType, componentId, componentInstance, - NodeFilterConstraintType.PROPERTIES_PARAM_NAME, 1); + NodeFilterConstraintType.PROPERTIES_PARAM_NAME, 0); final Response response = target() .path(path) .request(MediaType.APPLICATION_JSON) 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 39259a899f..2da9efbb6d 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 @@ -403,4 +403,5 @@ public class ComponentSubstitutionFilterServletTest extends JerseyTest { return mapper.writeValueAsString(uiConstraint); } -}
\ No newline at end of file +} + diff --git a/catalog-model/src/main/java/org/openecomp/sdc/be/ui/model/UIConstraint.java b/catalog-model/src/main/java/org/openecomp/sdc/be/ui/model/UIConstraint.java index 75d8f69eb7..779dfbe289 100644 --- a/catalog-model/src/main/java/org/openecomp/sdc/be/ui/model/UIConstraint.java +++ b/catalog-model/src/main/java/org/openecomp/sdc/be/ui/model/UIConstraint.java @@ -16,8 +16,6 @@ package org.openecomp.sdc.be.ui.model; -import com.google.common.base.MoreObjects; -import com.google.common.base.Objects; import java.io.Serializable; import lombok.EqualsAndHashCode; import lombok.Getter; @@ -30,6 +28,7 @@ import lombok.ToString; @ToString public class UIConstraint implements Serializable { + private String capabilityName; private String servicePropertyName; private String constraintOperator; private String sourceType; diff --git a/catalog-ui/src/app/models/tosca-filter-constraint-type.enum.ts b/catalog-ui/src/app/models/tosca-filter-constraint-type.enum.ts index 0a0cbeb4bf..64c0e026ac 100644 --- a/catalog-ui/src/app/models/tosca-filter-constraint-type.enum.ts +++ b/catalog-ui/src/app/models/tosca-filter-constraint-type.enum.ts @@ -18,5 +18,6 @@ */ export enum ToscaFilterConstraintType { - PROPERTIES = 'properties' + PROPERTIES = 'properties', + CAPABILITIES = 'capabilities' } diff --git a/catalog-ui/src/app/ng2/app.module.ts b/catalog-ui/src/app/ng2/app.module.ts index b3c12a5f11..b94ba61f75 100644 --- a/catalog-ui/src/app/ng2/app.module.ts +++ b/catalog-ui/src/app/ng2/app.module.ts @@ -95,6 +95,7 @@ import { PropertyCreatorModule } from './pages/properties-assignment/property-cr import { DeclareListModule } from './pages/properties-assignment/declare-list/declare-list.module'; import { WorkflowServiceNg2 } from './services/workflow.service'; import { ToscaTypesServiceNg2 } from "./services/tosca-types.service"; +import {CapabilitiesFilterPropertiesEditorComponentModule} from "./pages/composition/capabilities-filter-properties-editor/capabilities-filter-properties-editor.module"; declare const __ENV__: string; @@ -154,6 +155,7 @@ export function configServiceFactory(config: ConfigService, authService: Authent ServiceConsumptionCreatorModule, ServiceDependenciesModule, ServiceDependenciesEditorModule, + CapabilitiesFilterPropertiesEditorComponentModule, WorkspaceModule, ModalsModule, CatalogModule, diff --git a/catalog-ui/src/app/ng2/components/logic/capabilities-constraint/capabilities-constraint.component.ts b/catalog-ui/src/app/ng2/components/logic/capabilities-constraint/capabilities-constraint.component.ts new file mode 100644 index 0000000000..853106c806 --- /dev/null +++ b/catalog-ui/src/app/ng2/components/logic/capabilities-constraint/capabilities-constraint.component.ts @@ -0,0 +1,61 @@ +/* +* ============LICENSE_START======================================================= +* SDC +* ================================================================================ +* Copyright (C) 2020 Nordix Foundation. 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. +* +* SPDX-License-Identifier: Apache-2.0 +* ============LICENSE_END========================================================= +*/ + +export class CapabilitiesConstraintObject { + capabilityName: string; + servicePropertyName: string; + constraintOperator: string; + sourceType: string; + sourceName: string; + value: string; + + constructor(input?: any) { + if (input) { + this.capabilityName = input.capabilityName; + this.servicePropertyName = input.servicePropertyName; + this.constraintOperator = input.constraintOperator; + this.sourceType = input.sourceType; + this.sourceName = input.sourceName; + this.value = input.value; + } + } +} + +export class CapabilitiesConstraintObjectUI extends CapabilitiesConstraintObject{ + 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; + } +} 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 ef5e29b049..5f6e992d96 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 @@ -24,13 +24,13 @@ [ngClass]="{'hand': !readonly}" *ngFor="let capability of constraintCapabilities; let i = index"> <div class="filter-details" [ngClass]="{'readonly': readonly}"> - <div class="filter-desc" (click)="!readonly && onSelectNodeFilter(capabilities, i)" + <div class="filter-desc" (click)="!readonly && onSelectNodeFilterCapability(capabilities, i)" tooltips - tooltip="{{capability.servicePropertyName + ' ' + getSymbol(capability.constraintOperator) + ' ' - + (capability.sourceName ? capability.sourceName + ':' : '') + capability.value}}"> - {{capability.servicePropertyName + ' ' + getSymbol(capability.constraintOperator) - + ' ' - + (capability.sourceName ? capability.sourceName + ':' : '') + capability.value}} + tooltip="{{capability.capabilityName + ' : ' + + capability.servicePropertyName + ' ' + getSymbol(capability.constraintOperator) + ' ' + + (capability.sourceName ? capability.sourceName + ':' : '') + capability.value}}"> + {{capability.capabilityName + ' : ' + capability.servicePropertyName + ' ' + getSymbol(capability.constraintOperator) + + ' ' + (capability.sourceName ? capability.sourceName + ':' : '') + capability.value}} </div> <span *ngIf="!readonly" class="sprite-new delete-btn delete-icon" (click)="openDeleteModal(capabilities, i)" @@ -42,7 +42,7 @@ <button class="w-sdc-designer-sidebar-section-node-filter-footer-action add-rule-btn tlv-btn blue" data-tests-id="add-rule-button" - (click)="onAddNodeFilter(capabilities)" + (click)="onAddNodeFilterCapabilities()" [disabled]="readonly"> {{'DIRECTIVES_AND_NODE_FILTER_ADD_NODE_FILTER' | translate}} </button> @@ -75,7 +75,7 @@ <button class="w-sdc-designer-sidebar-section-node-filter-footer-action add-rule-btn tlv-btn blue" data-tests-id="add-rule-button" - (click)="onAddNodeFilter(properties)" + (click)="onAddNodeFilter()" [disabled]="readonly"> {{'DIRECTIVES_AND_NODE_FILTER_ADD_NODE_FILTER' | translate}} </button> 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 ff5207bb2c..ff3779119d 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 @@ -20,6 +20,7 @@ import { 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'; @@ -29,6 +30,9 @@ 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 {CapabilitiesConstraintObject} from "../capabilities-constraint/capabilities-constraint.component"; +import {ToscaFilterConstraintType} from "../../../../models/tosca-filter-constraint-type.enum"; export class ConstraintObject { servicePropertyName: string; @@ -91,6 +95,8 @@ class I18nTexts { static updateNodeFilterTxt: string; static deleteNodeFilterTxt: string; static deleteNodeFilterMsg: string; + static validateCapabilitiesTxt: string + static validateCapabilitiesMsg: string public static translateTexts(translateService) { I18nTexts.removeDirectiveModalTitle = translateService.translate('DIRECTIVES_AND_NODE_FILTER_REMOVE_TITLE'); @@ -106,6 +112,8 @@ class I18nTexts { I18nTexts.updateNodeFilterTxt = translateService.translate('DIRECTIVES_AND_NODE_FILTER_UPDATE_NODE_FILTER'); I18nTexts.deleteNodeFilterTxt = translateService.translate('DIRECTIVES_AND_NODE_FILTER_DELETE_NODE_FILTER'); I18nTexts.deleteNodeFilterMsg = translateService.translate('DIRECTIVES_AND_NODE_FILTER_DELETE_NODE_FILTER_MSG'); + I18nTexts.validateCapabilitiesTxt = translateService.translate('VALIDATE_CAPABILITIES_TXT'); + I18nTexts.validateCapabilitiesMsg = translateService.translate('VALIDATE_CAPABILITIES_MSG'); } } @@ -123,10 +131,10 @@ export class ServiceDependenciesComponent { isLoading: boolean; parentServiceInputs: InputBEModel[] = []; constraintProperties: ConstraintObject[] = []; - constraintCapabilities: ConstraintObject[] = []; + constraintCapabilities: CapabilitiesConstraintObject[] = []; operatorTypes: any[]; - capabilities: string = 'capabilities'; - properties: string = 'properties'; + capabilities: string = ToscaFilterConstraintType.CAPABILITIES; + properties: string = ToscaFilterConstraintType.PROPERTIES; private componentInstancesConstraints: ConstraintObject[] = []; directiveOptions: string[]; @@ -138,10 +146,12 @@ export class ServiceDependenciesComponent { @Input() selectedInstanceProperties: PropertyBEModel[] = []; @Output() updateRulesListEvent: EventEmitter<ConstraintObject[]> = new EventEmitter<ConstraintObject[]>(); @Output() updateNodeFilterProperties: EventEmitter<ConstraintObject[]> = new EventEmitter<ConstraintObject[]>(); - @Output() updateNodeFilterCapabilities: EventEmitter<ConstraintObject[]> = new EventEmitter<ConstraintObject[]>(); + @Output() updateNodeFilterCapabilities: EventEmitter<CapabilitiesConstraintObject[]> = new EventEmitter<CapabilitiesConstraintObject[]>(); @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) { } @@ -205,7 +215,7 @@ export class ServiceDependenciesComponent { this.componentInstancesConstraints = response.nodeFilterforNode; const nodeFilterPropertiesResponse: ConstraintObject[] = response.nodeFilterforNode[this.currentServiceInstance.uniqueId].properties; this.constraintProperties = nodeFilterPropertiesResponse; - const nodeFilterCapabilitiesResponse: ConstraintObject[] = response.nodeFilterforNode[this.currentServiceInstance.uniqueId].capabilities; + const nodeFilterCapabilitiesResponse: CapabilitiesConstraintObject[] = response.nodeFilterforNode[this.currentServiceInstance.uniqueId].capabilities; this.constraintCapabilities = nodeFilterCapabilitiesResponse; } }); @@ -270,10 +280,9 @@ export class ServiceDependenciesComponent { }); } - onAddNodeFilter = (constraintType: string) => { - console.info("constraintType: ", constraintType); + onAddNodeFilter = () => { const cancelButton: ButtonModel = new ButtonModel(I18nTexts.modalCancel, 'outline white', this.modalServiceNg2.closeCurrentModal); - const saveButton: ButtonModel = new ButtonModel(I18nTexts.modalCreate, 'blue', () => this.createNodeFilter(constraintType), this.getDisabled); + const saveButton: ButtonModel = new ButtonModel(I18nTexts.modalCreate, 'blue', () => this.createNodeFilter(this.properties), this.getDisabled); const modalModel: ModalModel = new ModalModel('l', I18nTexts.addNodeFilterTxt, '', [saveButton, cancelButton], 'standard'); this.modalInstance = this.modalServiceNg2.createCustomModal(modalModel); this.modalServiceNg2.addDynamicContentToModal( @@ -291,9 +300,92 @@ export class ServiceDependenciesComponent { this.modalInstance.instance.open(); } + onAddNodeFilterCapabilities = () => { + if (this.componentInstanceCapabilitiesMap.size == 0) { + this.modalServiceNg2.openAlertModal(I18nTexts.validateCapabilitiesTxt, I18nTexts.validateCapabilitiesMsg); + } else { + const cancelButton: ButtonModel = new ButtonModel(I18nTexts.modalCancel, 'outline white', this.modalServiceNg2.closeCurrentModal); + const saveButton: ButtonModel = new ButtonModel(I18nTexts.modalCreate, 'blue', () => this.createNodeFilterCapabilities(this.capabilities), this.getDisabled); + const modalModel: ModalModel = new ModalModel('l', I18nTexts.addNodeFilterTxt, '', [saveButton, cancelButton], 'standard'); + this.modalInstance = this.modalServiceNg2.createCustomModal(modalModel); + this.modalServiceNg2.addDynamicContentToModal( + this.modalInstance, + CapabilitiesFilterPropertiesEditorComponent, + { + currentServiceName: this.currentServiceInstance.name, + operatorTypes: this.operatorTypes, + compositeServiceName: this.compositeService.name, + parentServiceInputs: this.parentServiceInputs, + selectedInstanceProperties: this.selectedInstanceProperties, + selectedInstanceSiblings: this.selectedInstanceSiblings, + componentInstanceCapabilitiesMap: this.componentInstanceCapabilitiesMap + } + ); + this.modalInstance.instance.open(); + } + } + + createNodeFilter = (constraintType: string) => { + this.isLoading = true; + this.topologyTemplateService.createServiceFilterConstraints( + this.compositeService.uniqueId, + this.currentServiceInstance.uniqueId, + new ConstraintObject(this.modalInstance.instance.dynamicContent.instance.currentRule), + this.compositeService.componentType, + constraintType + ).subscribe( (response) => { + this.emitEventOnChanges(constraintType, response); + this.isLoading = false; + }, (err) => { + this.isLoading = false; + }); + this.modalServiceNg2.closeCurrentModal(); + } + + createNodeFilterCapabilities = (constraintType: string) => { + this.isLoading = true; + this.topologyTemplateService.createServiceFilterCapabilitiesConstraints( + this.compositeService.uniqueId, + this.currentServiceInstance.uniqueId, + new CapabilitiesConstraintObject(this.modalInstance.instance.dynamicContent.instance.currentRule), + this.compositeService.componentType, + constraintType + ).subscribe( (response) => { + this.emitEventOnChanges(constraintType, response); + this.isLoading = false; + }, (err) => { + this.isLoading = false; + }); + this.modalServiceNg2.closeCurrentModal(); + } + + onSelectNodeFilterCapability(constraintType: string, index: number) { + 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'); + this.modalInstance = this.modalServiceNg2.createCustomModal(modalModel); + + this.modalServiceNg2.addDynamicContentToModal( + this.modalInstance, + CapabilitiesFilterPropertiesEditorComponent, + { + serviceRuleIndex: index, + serviceRules: _.map(this.constraintCapabilities, (rule) => new CapabilitiesConstraintObject(rule)), + currentServiceName: this.currentServiceInstance.name, + operatorTypes: this.operatorTypes, + compositeServiceName: this.compositeService.name, + parentServiceInputs: this.parentServiceInputs, + selectedInstanceProperties: this.selectedInstanceProperties, + selectedInstanceSiblings: this.selectedInstanceSiblings, + componentInstanceCapabilitiesMap: this.componentInstanceCapabilitiesMap + } + ); + this.modalInstance.instance.open(); + } + onSelectNodeFilter(constraintType: string, index: number) { const cancelButton: ButtonModel = new ButtonModel(I18nTexts.modalCancel, 'outline white', this.modalServiceNg2.closeCurrentModal); - const saveButton: ButtonModel = new ButtonModel(I18nTexts.modalSave, 'blue', () => this.updateNodeFilter(constraintType), this.getDisabled); + 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'); this.modalInstance = this.modalServiceNg2.createCustomModal(modalModel); this.modalServiceNg2.addDynamicContentToModal( @@ -301,8 +393,7 @@ export class ServiceDependenciesComponent { ServiceDependenciesEditorComponent, { serviceRuleIndex: index, - serviceRules: _.map(this.properties == constraintType ? this.constraintProperties : - this.constraintCapabilities, (rule) => new ConstraintObjectUI(rule)), + serviceRules: _.map(this.constraintProperties, (rule) => new ConstraintObjectUI(rule)), currentServiceName: this.currentServiceInstance.name, operatorTypes: this.operatorTypes, compositeServiceName: this.compositeService.name, @@ -315,19 +406,19 @@ export class ServiceDependenciesComponent { } getDisabled = (): boolean => { - return !this.modalInstance.instance.dynamicContent.instance.checkFormValidForSubmit(); + return false; } - createNodeFilter = (constraintType: string) => { - const newRuleToCreate: ConstraintObject = new ConstraintObject(this.modalInstance.instance.dynamicContent.instance.currentRule); + updateNodeFilter = (constraintType: string, index: number) => { this.isLoading = true; - this.topologyTemplateService.createServiceFilterConstraints( + this.topologyTemplateService.updateServiceFilterConstraints( this.compositeService.uniqueId, this.currentServiceInstance.uniqueId, - newRuleToCreate, + new ConstraintObject(this.modalInstance.instance.dynamicContent.instance.currentRule), this.compositeService.componentType, - constraintType - ).subscribe( (response) => { + constraintType, + index + ).subscribe((response) => { this.emitEventOnChanges(constraintType, response); this.isLoading = false; }, (err) => { @@ -336,15 +427,15 @@ export class ServiceDependenciesComponent { this.modalServiceNg2.closeCurrentModal(); } - updateNodeFilter = (constraintType: string) => { - const allRulesToUpdate: ConstraintObject[] = this.modalInstance.instance.dynamicContent.instance.serviceRulesList.map((rule) => new ConstraintObject(rule)); + updateNodeFilterCapability= (constraintType: string, index: number) => { this.isLoading = true; - this.topologyTemplateService.updateServiceFilterConstraints( + this.topologyTemplateService.updateServiceFilterCapabilitiesConstraint( this.compositeService.uniqueId, this.currentServiceInstance.uniqueId, - allRulesToUpdate, + new CapabilitiesConstraintObject(this.modalInstance.instance.dynamicContent.instance.currentRule), this.compositeService.componentType, - constraintType + constraintType, + index ).subscribe((response) => { this.emitEventOnChanges(constraintType, response); this.isLoading = false; diff --git a/catalog-ui/src/app/ng2/pages/composition/capabilities-filter-properties-editor/capabilities-filter-properties-editor.component.html b/catalog-ui/src/app/ng2/pages/composition/capabilities-filter-properties-editor/capabilities-filter-properties-editor.component.html new file mode 100644 index 0000000000..1dcbc16c12 --- /dev/null +++ b/catalog-ui/src/app/ng2/pages/composition/capabilities-filter-properties-editor/capabilities-filter-properties-editor.component.html @@ -0,0 +1,81 @@ +<!-- + * ============LICENSE_START======================================================= + * SDC + * ================================================================================ + * Copyright (C) 2020 Nordix Foundation. 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========================================================= +--> + +<div class="app-capabilities-filter-properties-editor"> + <form class="w-sdc-form"> + <loader [display]="isLoading" [size]="'large'" [relative]="true"></loader> + <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}} Capabilities</label> + <ui-element-dropdown class="i-sdc-form-select" class="rule-assigned-value" + [(value)]="currentRule.capabilityName" + [values]="capabilitiesNames" + (elementChanged)="onCapabilityNameChanged($event.value)"> + </ui-element-dropdown> + </div> + + <div class="i-sdc-form-item rule-input-field"> + <label class="i-sdc-form-label required">Capability Properties</label> + <ui-element-dropdown class="i-sdc-form-select" class="rule-assigned-value" + [(value)]="this.currentRule.servicePropertyName" + [values]="capabilityProperties" + (change)="onServicePropertyChanged()"> + </ui-element-dropdown> + </div> + + <div class="i-sdc-form-item rule-input-field operator"> + <ui-element-dropdown class="i-sdc-form-select" + [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" >Source</label> + <ui-element-dropdown class="i-sdc-form-select" + [values]="sourceTypes" + [(value)]="currentRule.sourceName" + (change)="onSelectSourceType()"> + </ui-element-dropdown> + </div> + + <div class="rule-input-field assigned-value-field"> + <label class="i-sdc-form-label required" >{{assignedValueLabel}}</label> + <dynamic-element + *ngIf="currentRule.sourceType === SOURCE_TYPES.STATIC.value" + [(value)]="currentRule.value" + class="rule-assigned-value" + data-tests-id="ruleAssignedValue" + (elementChanged)="onValueChange($event.isValid)" + [type]="selectedCapabilitiesPropertyObject ? selectedCapabilitiesPropertyObject.type : 'string'"> + </dynamic-element> + <ui-element-dropdown *ngIf="currentRule.sourceType !== SOURCE_TYPES.STATIC.value" + class="rule-assigned-value" + 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/composition/capabilities-filter-properties-editor/capabilities-filter-properties-editor.component.less b/catalog-ui/src/app/ng2/pages/composition/capabilities-filter-properties-editor/capabilities-filter-properties-editor.component.less new file mode 100644 index 0000000000..188fb7b5ef --- /dev/null +++ b/catalog-ui/src/app/ng2/pages/composition/capabilities-filter-properties-editor/capabilities-filter-properties-editor.component.less @@ -0,0 +1,44 @@ +@import './../../../../../assets/styles/variables.less'; + + +.sdc-modal-top-bar { + display: flex; + justify-content: flex-end; +} + +.i-sdc-form-content { + display: flex; + flex-direction: column; + margin-top: 10px; + padding-bottom: 20px; + + .i-sdc-form-item { + width: 250px; + &.operation { + width: 60px; + } + } + + .rule-builder-content { + display: flex; + align-items: flex-end; + .rule-input-field { + flex: 1; + &:not(:last-of-type) { + margin-right: 20px; + } + &.operator{ + width: 55px; + flex: 0 1 auto; + } + &.assigned-value-field { + margin-bottom: 10px; + } + /deep/ ui-element-dropdown select, + /deep/ ui-element-input input { + height: 30px; + } + } + + } +} 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 new file mode 100644 index 0000000000..1205556ee0 --- /dev/null +++ b/catalog-ui/src/app/ng2/pages/composition/capabilities-filter-properties-editor/capabilities-filter-properties-editor.component.ts @@ -0,0 +1,214 @@ +/* +* ============LICENSE_START======================================================= +* SDC +* ================================================================================ +* Copyright (C) 2020 Nordix Foundation. 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. +* +* SPDX-License-Identifier: Apache-2.0 +* ============LICENSE_END========================================================= +*/ + +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"; + +export class UIDropDownSourceTypesElement extends DropdownValue { + options: any[]; + assignedLabel: string; + type: string; + constructor(input?: any) { + if (input) { + const value = input.value || ''; + const label = input.label || ''; + super(value, label); + this.options = input.options; + this.assignedLabel = input.assignedLabel; + this.type = input.type; + } + } +} + +@Component({ + selector: 'app-capabilities-filter-properties-editor', + templateUrl: './capabilities-filter-properties-editor.component.html', + styleUrls: ['./capabilities-filter-properties-editor.component.less'], + providers: [ServiceServiceNg2] +}) +export class CapabilitiesFilterPropertiesEditorComponent { + + constructor() { + } + + input: { + serviceRuleIndex: number, + serviceRules: CapabilitiesConstraintObjectUI[], + compositeServiceName: string, + currentServiceName: string, + parentServiceInputs: InputBEModel[], + selectedInstanceProperties: PropertyBEModel[], + operatorTypes: DropdownValue[], + selectedInstanceSiblings: ServiceInstanceObject[], + componentInstanceCapabilitiesMap: Map<string, PropertyModel[]>, + }; + currentServiceName: string; + selectedServiceProperties: PropertyBEModel[]; + operatorTypes: DropdownValue[]; + sourceTypes: UIDropDownSourceTypesElement[] = []; + currentRule: CapabilitiesConstraintObjectUI; + currentIndex: number; + listOfValuesToAssign: DropdownValue[]; + listOfSourceOptions: PropertyBEModel[]; + assignedValueLabel: string; + serviceRulesList: CapabilitiesConstraintObjectUI[]; + + capabilitiesNames: string[]; + selectedPropertiesByCapabilityName: Array<PropertyModel>; + selectedCapabilityName: string; + capabilityProperties: DropdownValue[]; + + selectedCapabilitiesPropertyObject: PropertyBEModel; + + SOURCE_TYPES = { + STATIC: {label: 'Static', value: 'static'}, + SERVICE_PROPERTY: {label: 'Service Property', value: 'property'}, + CAPABILITY_NAME: {label: 'Name', value: 'name'} + }; + + ngOnInit() { + this.capabilitiesNames = Array.from(this.input.componentInstanceCapabilitiesMap.keys()); + this.currentIndex = this.input.serviceRuleIndex; + this.serviceRulesList = this.input.serviceRules; + this.currentRule = this.serviceRulesList && this.input.serviceRuleIndex >= 0 ? + this.serviceRulesList[this.input.serviceRuleIndex] : + new CapabilitiesConstraintObjectUI({ + capabilityName: this.SOURCE_TYPES.CAPABILITY_NAME.value, + sourceName: this.SOURCE_TYPES.STATIC.value, + sourceType: this.SOURCE_TYPES.STATIC.value, value: '', + constraintOperator: OPERATOR_TYPES.EQUAL}); + this.currentServiceName = this.input.currentServiceName; + this.operatorTypes = this.input.operatorTypes; + + this.initSourceTypes(); + this.syncRuleData(); + this.updateSourceTypesRelatedValues(); + this.onCapabilityNameChanged(this.currentRule.capabilityName) + } + + initSourceTypes() { + this.sourceTypes.push({label: this.SOURCE_TYPES.STATIC.label, value: this.SOURCE_TYPES.STATIC.value, + options: [], assignedLabel: this.SOURCE_TYPES.STATIC.label, type: this.SOURCE_TYPES.STATIC.value}); + this.sourceTypes.push({ + label: this.input.compositeServiceName, + value: this.input.compositeServiceName, + assignedLabel: this.SOURCE_TYPES.SERVICE_PROPERTY.label, + type: this.SOURCE_TYPES.SERVICE_PROPERTY.value, + options: this.input.parentServiceInputs + }); + _.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 + }) + ); + } + + syncRuleData() { + if (!this.currentRule.sourceName && this.currentRule.sourceType === this.SOURCE_TYPES.STATIC.value) { + this.currentRule.sourceName = this.SOURCE_TYPES.STATIC.value; + } + this.selectedCapabilitiesPropertyObject = Array.from(this.input.componentInstanceCapabilitiesMap + .get(this.currentRule.capabilityName)) + .find(property => property.name == this.currentRule.servicePropertyName); + this.updateOperatorTypesList(); + this.updateSourceTypesRelatedValues(); + } + + updateOperatorTypesList() { + if (this.selectedCapabilitiesPropertyObject && PROPERTY_DATA.SIMPLE_TYPES_COMPARABLE.indexOf(this.selectedCapabilitiesPropertyObject.type) === -1) { + this.operatorTypes = [{label: '=', value: OPERATOR_TYPES.EQUAL}]; + this.currentRule.constraintOperator = OPERATOR_TYPES.EQUAL; + } else { + this.operatorTypes = this.input.operatorTypes; + } + } + + 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 = selectedSourceType.options || []; + this.assignedValueLabel = selectedSourceType.assignedLabel || this.SOURCE_TYPES.STATIC.label; + this.filterOptionsByType(); + } + } + } + + onCapabilityNameChanged= (value: any): void => { + this.selectedPropertiesByCapabilityName = this.input.componentInstanceCapabilitiesMap.get(value); + this.capabilityProperties = _.map(this.selectedPropertiesByCapabilityName, (prop) => new DropdownValue(prop.name, prop.name)); + this.selectedCapabilityName = value; + this.updateOperatorTypesList(); + this.filterOptionsByType(); + } + + onServicePropertyChanged() { + this.updateOperatorTypesList(); + this.filterOptionsByType(); + this.currentRule.value = ''; + } + + onSelectSourceType() { + this.currentRule.sourceType = this.currentRule.sourceName === this.SOURCE_TYPES.STATIC.value ? + this.SOURCE_TYPES.STATIC.value : + this.SOURCE_TYPES.SERVICE_PROPERTY.value; + this.updateSourceTypesRelatedValues(); + this.currentRule.value = ''; + } + + filterOptionsByType() { + if (!this.selectedCapabilitiesPropertyObject) { + this.listOfValuesToAssign = []; + return; + } + this.listOfValuesToAssign = this.listOfSourceOptions.reduce((result, op: PropertyModel) => { + if (op.type === this.selectedCapabilitiesPropertyObject.type && (!op.schemaType || op.schemaType === this.selectedCapabilitiesPropertyObject.schemaType)) { + result.push(new DropdownValue(op.name, op.name)); + } + return result; + }, []); + } + + onValueChange(isValidValue) { + this.currentRule.updateValidity(isValidValue); + } + + checkFormValidForSubmit() { + if (!this.serviceRulesList) { + const isStatic = this.currentRule.sourceName === this.SOURCE_TYPES.STATIC.value; + return this.currentRule.isValidRule(isStatic); + } + return this.serviceRulesList.every((rule) => rule.isValidRule(rule.sourceName === this.SOURCE_TYPES.STATIC.value)); + } + +} diff --git a/catalog-ui/src/app/ng2/pages/composition/capabilities-filter-properties-editor/capabilities-filter-properties-editor.module.ts b/catalog-ui/src/app/ng2/pages/composition/capabilities-filter-properties-editor/capabilities-filter-properties-editor.module.ts new file mode 100644 index 0000000000..27bcb8a4e0 --- /dev/null +++ b/catalog-ui/src/app/ng2/pages/composition/capabilities-filter-properties-editor/capabilities-filter-properties-editor.module.ts @@ -0,0 +1,46 @@ +/* +* ============LICENSE_START======================================================= +* SDC +* ================================================================================ +* Copyright (C) 2020 Nordix Foundation. 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. +* +* SPDX-License-Identifier: Apache-2.0 +* ============LICENSE_END========================================================= +*/ + +import {CommonModule} from '@angular/common'; +import {NgModule} from '@angular/core'; +import {FormsModule} from '@angular/forms'; +import {FormElementsModule} from 'app/ng2/components/ui/form-components/form-elements.module'; +import {UiElementsModule} from 'app/ng2/components/ui/ui-elements.module'; +import {CapabilitiesFilterPropertiesEditorComponent} from "./capabilities-filter-properties-editor.component"; + +@NgModule({ + declarations: [ + CapabilitiesFilterPropertiesEditorComponent + ], + imports: [ + CommonModule, + FormsModule, + FormElementsModule, + UiElementsModule + ], + exports: [], + entryComponents: [ + CapabilitiesFilterPropertiesEditorComponent + ], + providers: [] +}) +export class CapabilitiesFilterPropertiesEditorComponentModule { +} diff --git a/catalog-ui/src/app/ng2/pages/composition/panel/panel-tabs/service-dependencies-tab/service-dependencies-tab.component.html b/catalog-ui/src/app/ng2/pages/composition/panel/panel-tabs/service-dependencies-tab/service-dependencies-tab.component.html index 508584d486..588ac8359b 100644 --- a/catalog-ui/src/app/ng2/pages/composition/panel/panel-tabs/service-dependencies-tab/service-dependencies-tab.component.html +++ b/catalog-ui/src/app/ng2/pages/composition/panel/panel-tabs/service-dependencies-tab/service-dependencies-tab.component.html @@ -6,6 +6,7 @@ [compositeService]="metaData" [currentServiceInstance]="component" [selectedInstanceProperties]="selectedInstanceProperties" + [componentInstanceCapabilitiesMap]="componentInstanceCapabilitiesMap" [selectedInstanceSiblings]="selectedInstanceSiblings" [selectedInstanceConstraints]="selectedInstanceConstraints" [readonly]="isViewOnly" 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 43c38b58b0..f844dfae4c 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 @@ -1,10 +1,11 @@ import {Component, Input} from '@angular/core'; import {Store} from '@ngxs/store'; import { + CapabilitiesGroup, Capability, Component as TopologyTemplate, FullComponentInstance, PropertiesGroup, - PropertyBEModel, + PropertyBEModel, PropertyModel, } from 'app/models'; import {DEPENDENCY_EVENTS} from 'app/utils/constants'; import {ComponentMetadata} from '../../../../../../models/component-metadata'; @@ -16,6 +17,7 @@ import {ComponentGenericResponse} from '../../../../../services/responses/compon 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"; @Component({ selector: 'service-dependencies-tab', @@ -30,7 +32,10 @@ export class ServiceDependenciesTabComponent { selectedInstanceConstraints: ConstraintObject[]; selectedInstanceProperties: PropertyBEModel[]; componentInstanceProperties: PropertiesGroup; + componentInstanceCapabilityProperties: CapabilitiesGroup; metaData: ComponentMetadata; + componentInstanceCapabilitiesMap : Map<string, PropertyModel[]> = new Map(); + componentInstanceCapabilitiesNames: string[]; @Input() isViewOnly: boolean; @Input() componentType: SelectedComponentType; @@ -50,6 +55,7 @@ export class ServiceDependenciesTabComponent { this.initInstancesWithProperties(); this.loadConstraints(); this.initInstancesWithProperties(); + this.initInstancesWithCapabilityProperties() } public loadConstraints = (): void => { @@ -67,7 +73,7 @@ export class ServiceDependenciesTabComponent { this.selectedInstanceConstraints = this.componentInstancesConstraints[this.component.uniqueId].properties; } - public updateSelectedInstanceCapabilitiesConstraints = (constraintsList:Array<ConstraintObject>):void => { + public updateSelectedInstanceCapabilitiesConstraints = (constraintsList:Array<CapabilitiesConstraintObject>):void => { this.componentInstancesConstraints[this.component.uniqueId].capabilities = constraintsList; this.selectedInstanceConstraints = this.componentInstancesConstraints[this.component.uniqueId].capabilities; } @@ -90,4 +96,20 @@ export class ServiceDependenciesTabComponent { this.selectedInstanceSiblings = instancesMappedList.filter((coInstance) => coInstance.id !== this.component.uniqueId); } } + + private initInstancesWithCapabilityProperties = (): void => { + this.componentInstanceCapabilityProperties = this.component.capabilities; + this.updateComponentInstanceCapabilities(); + } + + private updateComponentInstanceCapabilities = (): void => { + if (this.isComponentInstanceSelected && this.componentInstanceCapabilityProperties) { + _.forEach(_.flatten(_.values(this.componentInstanceCapabilityProperties)), (capability: Capability) => { + if (capability.properties) { + this.componentInstanceCapabilitiesMap.set(capability.name, capability.properties); + } + }); + } + } + } 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 f22e454332..4b23568a06 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 @@ -1,13 +1,6 @@ <div class="service-dependencies-editor"> <form class="w-sdc-form"> - <div class="sdc-modal-top-bar"> - <div class="sdc-modal-top-bar-buttons" *ngIf="currentIndex >= 0"> - <span (click)="onChangePage(currentIndex - 1)" [ngClass]="{'disabled' : currentIndex === 0}" class="sprite-new left-arrow" data-tests-id="get-prev-rule" tooltip="Previous"></span> - <span (click)="onChangePage(currentIndex + 1)" [ngClass]="{'disabled' : currentIndex === input.serviceRules.length - 1}" class="sprite-new right-arrow" data-tests-id="get-next-rule" tooltip="Next"></span> - </div> - </div> - <loader [display]="isLoading" [size]="'large'" [relative]="true"></loader> <div class="i-sdc-form-content"> @@ -53,4 +46,4 @@ </div> </form> -</div>
\ No newline at end of file +</div> 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 175069e9a2..14bf84599c 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 @@ -35,7 +35,7 @@ import { PropertyModel, IFileDownload, AttributeModel, - IAttributeModel, Capability, Requirement + Capability, Requirement } from "app/models"; import {ArtifactGroupType, COMPONENT_FIELDS} from "app/utils"; import {ComponentGenericResponse} from "../responses/component-generic-response"; @@ -64,6 +64,7 @@ import { ComponentMetadata } from "../../../models/component-metadata"; 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"; /* 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*/ @@ -389,16 +390,29 @@ export class TopologyTemplateService { return this.getComponentDataByFieldsName(componentType, componentId, [COMPONENT_FIELDS.COMPONENT_INSTANCES_PROPERTIES]); } + getComponentInstanceCapabilityProperties(componentType: string, componentId: string): Observable<ComponentGenericResponse> { + return this.getComponentDataByFieldsName(componentType, componentId, + [COMPONENT_FIELDS.COMPONENT_CAPABILITIES, COMPONENT_FIELDS.COMPONENT_CAPABILITIES_PROPERTIES]); + } + createServiceFilterConstraints(componentMetaDataId: string, componentInstanceId: string, constraint: ConstraintObject, componentType: string, constraintType: string): Observable<any> { - return this.http.post<any>(this.baseUrl + this.getServerTypeUrl(componentType) + componentMetaDataId + '/resourceInstances/' + componentInstanceId + '/nodeFilter/' + constraintType, constraint); + 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> { + 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, constraints: ConstraintObject[], componentType: string, constraintType: string):Observable<any>{ - return this.http.put<any>(this.baseUrl + this.getServerTypeUrl(componentType) + componentMetaDataId + '/resourceInstances/' + componentInstanceId + '/nodeFilter/' + constraintType, constraints) + updateServiceFilterCapabilitiesConstraint(componentMetaDataId: string, componentInstanceId: string, constraints: CapabilitiesConstraintObject, 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) } deleteServiceFilterConstraints(componentMetaDataId: string, componentInstanceId: string, constraintIndex: number, componentType: string, constraintType: string): Observable<any>{ - return this.http.delete<any>(this.baseUrl + this.getServerTypeUrl(componentType) + componentMetaDataId + '/resourceInstances/' + componentInstanceId + '/nodeFilter/' + constraintType + "/" + constraintIndex) + return this.http.delete<any>(this.baseUrl + this.getServerTypeUrl(componentType) + componentMetaDataId + '/componentInstance/' + componentInstanceId + '/' + constraintType + '/' + constraintIndex + '/nodeFilter') } getComponentPropertiesSubstitutionFilter(componentType: string, componentId: string): Observable<ComponentGenericResponse> { diff --git a/catalog-ui/src/assets/languages/en_US.json b/catalog-ui/src/assets/languages/en_US.json index cdd580cec6..2417b0d4ae 100644 --- a/catalog-ui/src/assets/languages/en_US.json +++ b/catalog-ui/src/assets/languages/en_US.json @@ -509,6 +509,8 @@ "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?", + "VALIDATE_CAPABILITIES_TXT": "Node Filter for Capabilities Properties", + "VALIDATE_CAPABILITIES_MSG": "The selected Component Instance does not have any capability property", "============= SUBSTITUTION FILTER MANAGE TAB ======" : "", "ADD_SUBSTITUTION_FILTER": "Add Substitution Filter", |