diff options
23 files changed, 588 insertions, 649 deletions
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 55c70ed271..74de13c952 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 @@ -36,7 +36,6 @@ import org.openecomp.sdc.be.datatypes.elements.RequirementSubstitutionFilterProp import org.openecomp.sdc.be.datatypes.elements.SubstitutionFilterDataDefinition; import org.openecomp.sdc.be.datatypes.enums.ComponentTypeEnum; import org.openecomp.sdc.be.model.Component; -import org.openecomp.sdc.be.model.ComponentInstance; import org.openecomp.sdc.be.model.User; import org.openecomp.sdc.be.model.jsonjanusgraph.operations.ArtifactsOperations; import org.openecomp.sdc.be.model.jsonjanusgraph.operations.InterfaceOperation; @@ -69,7 +68,8 @@ public class ComponentSubstitutionFilterBusinessLogic extends BaseBusinessLogic final InterfaceLifecycleOperation interfaceLifecycleTypeOperation, final ArtifactsOperations artifactToscaOperation, final SubstitutionFilterOperation substitutionFilterOperation, - final NodeFilterValidator nodeFilterValidator) { + NodeFilterValidator nodeFilterValidator) + { super(elementDao, groupOperation, groupInstanceOperation, groupTypeOperation, interfaceOperation, interfaceLifecycleTypeOperation, artifactToscaOperation); this.substitutionFilterOperation = substitutionFilterOperation; @@ -77,21 +77,14 @@ public class ComponentSubstitutionFilterBusinessLogic extends BaseBusinessLogic } public Optional<SubstitutionFilterDataDefinition> createSubstitutionFilterIfNotExist(final String componentId, - final String componentInstanceId, final boolean shouldLock, final ComponentTypeEnum componentTypeEnum) - throws BusinessLogicException { + throws BusinessLogicException { final Component component = getComponent(componentId); - final Optional<ComponentInstance> componentInstanceOptional = - getComponentInstance(componentInstanceId, component); - - Optional<SubstitutionFilterDataDefinition> substitutionFilterDataDefinition; - if (componentInstanceOptional.isPresent()) { - substitutionFilterDataDefinition = getSubstitutionFilterDataDefinition(componentInstanceOptional.get()); - if (substitutionFilterDataDefinition.isPresent()) { - return substitutionFilterDataDefinition; - } + Optional<SubstitutionFilterDataDefinition> substitutionFilterDataDefinition = Optional.ofNullable(component.getSubstitutionFilter()); + if (substitutionFilterDataDefinition.isPresent()) { + return substitutionFilterDataDefinition; } boolean wasLocked = false; try { @@ -100,24 +93,22 @@ public class ComponentSubstitutionFilterBusinessLogic extends BaseBusinessLogic wasLocked = true; } final Either<SubstitutionFilterDataDefinition, StorageOperationStatus> result = substitutionFilterOperation - .createSubstitutionFilter(componentId, componentInstanceId); + .createSubstitutionFilter(componentId); if (result.isRight()) { janusGraphDao.rollback(); LOGGER.error(BUSINESS_PROCESS_ERROR, - "Failed to Create Substitution filter on component with id {}", componentId); + "Failed to Create Substitution filter on component with id {}", componentId); throw new BusinessLogicException(componentsUtils.getResponseFormatByResource(componentsUtils - .convertFromStorageResponse(result.right().value()), component.getSystemName())); + .convertFromStorageResponse(result.right().value()), component.getSystemName())); } substitutionFilterDataDefinition = Optional.ofNullable(result.left().value()); - if (componentInstanceOptional.isPresent() && substitutionFilterDataDefinition.isPresent()) { - componentInstanceOptional.get().setSubstitutionFilter(substitutionFilterDataDefinition.get()); - } + component.setSubstitutionFilter(substitutionFilterDataDefinition.get()); janusGraphDao.commit(); LOGGER.debug("Substitution filter successfully created in component {} . ", component.getSystemName()); } catch (final Exception e) { janusGraphDao.rollback(); LOGGER.error(BUSINESS_PROCESS_ERROR, - "Exception occurred during add Component Substitution filter property values: {}", e.getMessage(), e); + "Exception occurred during add Component Substitution filter property values: {}", e.getMessage(), e); throw new BusinessLogicException(componentsUtils.getResponseFormat(ActionStatus.GENERAL_ERROR)); } finally { @@ -130,8 +121,6 @@ public class ComponentSubstitutionFilterBusinessLogic extends BaseBusinessLogic } public Optional<SubstitutionFilterDataDefinition> addSubstitutionFilter(final String componentId, - final String componentInstanceId, - final NodeFilterConstraintAction action, final String propertyName, final String constraint, final boolean shouldLock, @@ -139,9 +128,14 @@ public class ComponentSubstitutionFilterBusinessLogic extends BaseBusinessLogic throws BusinessLogicException { final Component component = getComponent(componentId); - SubstitutionFilterDataDefinition substitutionFilterDataDefinition = validateAndReturnSubstitutionFilterDefinition( - componentInstanceId, - action, constraint, component); + + final Either<Boolean, ResponseFormat> response = nodeFilterValidator + .validateComponentFilter(component, Collections.singletonList(constraint), NodeFilterConstraintAction.ADD); + if (response.isRight()) { + throw new BusinessLogicException(componentsUtils + .getResponseFormat(ActionStatus.SUBSTITUTION_FILTER_NOT_FOUND, response.right().value().getFormattedMessage())); + } + boolean wasLocked = false; try { if (shouldLock) { @@ -152,19 +146,19 @@ public class ComponentSubstitutionFilterBusinessLogic extends BaseBusinessLogic new RequirementSubstitutionFilterPropertyDataDefinition(); newProperty.setName(propertyName); newProperty.setConstraints(Collections.singletonList(constraint)); - final Either<SubstitutionFilterDataDefinition, StorageOperationStatus> result = substitutionFilterOperation - .addNewProperty(componentId, componentInstanceId, substitutionFilterDataDefinition, newProperty); + final Either<SubstitutionFilterDataDefinition, StorageOperationStatus> resultEither = + substitutionFilterOperation + .addPropertyFilter(componentId, component.getSubstitutionFilter(), newProperty); - if (result.isRight()) { + if (resultEither.isRight()) { janusGraphDao.rollback(); throw new BusinessLogicException(componentsUtils.getResponseFormatByResource(componentsUtils - .convertFromStorageResponse(result.right().value()), component.getSystemName())); - } else { - substitutionFilterDataDefinition = result.left().value(); + .convertFromStorageResponse(resultEither.right().value()), component.getSystemName())); } + janusGraphDao.commit(); LOGGER.debug("Substitution filter successfully created in component {} . ", component.getSystemName()); - + return Optional.ofNullable(resultEither.left().value()); } catch (final Exception e) { janusGraphDao.rollback(); LOGGER.error(BUSINESS_PROCESS_ERROR, @@ -176,11 +170,10 @@ public class ComponentSubstitutionFilterBusinessLogic extends BaseBusinessLogic unlockComponent(component.getUniqueId(), componentTypeEnum); } } - return Optional.ofNullable(substitutionFilterDataDefinition); + } public Optional<SubstitutionFilterDataDefinition> updateSubstitutionFilter(final String componentId, - final String componentInstanceId, final List<String> constraints, final boolean shouldLock, final ComponentTypeEnum componentTypeEnum) @@ -189,19 +182,13 @@ public class ComponentSubstitutionFilterBusinessLogic extends BaseBusinessLogic final Component component = getComponent(componentId); final Either<Boolean, ResponseFormat> response = nodeFilterValidator - .validateFilter(component, componentInstanceId, constraints, NodeFilterConstraintAction.UPDATE); + .validateComponentFilter(component, constraints, NodeFilterConstraintAction.UPDATE); if (response.isRight()) { throw new BusinessLogicException(componentsUtils - .getResponseFormat(SUBSTITUTION_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)); + .getResponseFormat(ActionStatus.SUBSTITUTION_FILTER_NOT_FOUND, response.right().value().getFormattedMessage())); } - SubstitutionFilterDataDefinition substitutionFilterDataDefinition = componentInstance.get() - .getSubstitutionFilter(); + + SubstitutionFilterDataDefinition substitutionFilterDataDefinition = component.getSubstitutionFilter(); if (substitutionFilterDataDefinition == null) { throw new BusinessLogicException(componentsUtils.getResponseFormat(SUBSTITUTION_FILTER_NOT_FOUND)); } @@ -212,9 +199,9 @@ public class ComponentSubstitutionFilterBusinessLogic extends BaseBusinessLogic wasLocked = true; } final List<RequirementSubstitutionFilterPropertyDataDefinition> properties = constraints.stream() - .map(this::getRequirementSubstitutionFilterPropertyDataDefinition).collect(Collectors.toList()); + .map(this::getRequirementSubstitutionFilterPropertyDataDefinition).collect(Collectors.toList()); final Either<SubstitutionFilterDataDefinition, StorageOperationStatus> result = substitutionFilterOperation - .updateSubstitutionFilter(componentId, componentInstanceId, substitutionFilterDataDefinition, properties); + .updateProperties(componentId, substitutionFilterDataDefinition, properties); if (result.isRight()) { janusGraphDao.rollback(); @@ -241,17 +228,13 @@ public class ComponentSubstitutionFilterBusinessLogic extends BaseBusinessLogic } public Optional<SubstitutionFilterDataDefinition> deleteSubstitutionFilter(final String componentId, - final String componentInstanceId, - final NodeFilterConstraintAction action, - final String constraint, final int position, final boolean shouldLock, final ComponentTypeEnum componentTypeEnum) throws BusinessLogicException { final Component component = getComponent(componentId); - SubstitutionFilterDataDefinition substitutionFilterDataDefinition = - validateAndReturnSubstitutionFilterDefinition(componentInstanceId, action, constraint, component); + SubstitutionFilterDataDefinition substitutionFilterDataDefinition = component.getSubstitutionFilter(); boolean wasLocked = false; try { if (shouldLock) { @@ -259,7 +242,7 @@ public class ComponentSubstitutionFilterBusinessLogic extends BaseBusinessLogic wasLocked = true; } final Either<SubstitutionFilterDataDefinition, StorageOperationStatus> result = substitutionFilterOperation - .deleteConstraint(componentId, componentInstanceId, substitutionFilterDataDefinition, position); + .deleteConstraint(componentId, substitutionFilterDataDefinition, position); if (result.isRight()) { janusGraphDao.rollback(); throw new BusinessLogicException(componentsUtils.getResponseFormatByResource(componentsUtils @@ -285,17 +268,6 @@ public class ComponentSubstitutionFilterBusinessLogic extends BaseBusinessLogic return Optional.ofNullable(substitutionFilterDataDefinition); } - private Optional<SubstitutionFilterDataDefinition> getSubstitutionFilterDataDefinition( - final ComponentInstance componentInstance) { - - final SubstitutionFilterDataDefinition substitutionFilterDataDefinition = - componentInstance.getSubstitutionFilter(); - if (componentInstance.getSubstitutionFilter() != null) { - return Optional.ofNullable(substitutionFilterDataDefinition); - } - return Optional.empty(); - } - private void unlockComponent(final String componentUniqueId, final ComponentTypeEnum componentType) { graphLockOperation.unlockComponent(componentUniqueId, componentType.getNodeType()); @@ -307,47 +279,6 @@ public class ComponentSubstitutionFilterBusinessLogic extends BaseBusinessLogic return user; } - private Optional<ComponentInstance> getComponentInstance(final String componentInstanceId, - final Component component) { - return component.getComponentInstanceById(componentInstanceId); - } - - private Optional<SubstitutionFilterDataDefinition> getComponentInstanceSubstitutionFilterDataDefinition( - final String componentInstanceId, final Component component) - throws BusinessLogicException { - - if (nodeFilterValidator.validateComponentInstanceExist(component, componentInstanceId).isRight()) { - throw new BusinessLogicException(componentsUtils - .getResponseFormat(SUBSTITUTION_FILTER_NOT_FOUND)); - } - return getComponentInstance(componentInstanceId, component).map(ComponentInstance::getSubstitutionFilter); - } - - private SubstitutionFilterDataDefinition validateAndReturnSubstitutionFilterDefinition( - final String componentInstanceId, final NodeFilterConstraintAction action, final String constraint, - final Component component) throws BusinessLogicException { - - validateSubstitutionFilter(component, componentInstanceId, action, constraint); - final Optional<SubstitutionFilterDataDefinition> substitutionFilterDataDefinition = - getComponentInstanceSubstitutionFilterDataDefinition(componentInstanceId, component); - if (!substitutionFilterDataDefinition.isPresent()) { - throw new BusinessLogicException(componentsUtils.getResponseFormat(SUBSTITUTION_FILTER_NOT_FOUND)); - } - return substitutionFilterDataDefinition.get(); - } - - private void validateSubstitutionFilter(final Component component, - final String componentInstanceId, - final NodeFilterConstraintAction action, - final String constraint) throws BusinessLogicException { - final Either<Boolean, ResponseFormat> response = nodeFilterValidator - .validateFilter(component, componentInstanceId, Collections.singletonList(constraint), action); - if (response.isRight()) { - throw new BusinessLogicException(componentsUtils - .getResponseFormat(SUBSTITUTION_FILTER_NOT_FOUND, response.right().value().getFormattedMessage())); - } - } - private RequirementSubstitutionFilterPropertyDataDefinition getRequirementSubstitutionFilterPropertyDataDefinition( final String constraint) { @@ -356,4 +287,4 @@ public class ComponentSubstitutionFilterBusinessLogic extends BaseBusinessLogic requirementSubstitutionFilterPropertyDataDefinition.setConstraints(Arrays.asList(constraint)); return requirementSubstitutionFilterPropertyDataDefinition; } -}
\ No newline at end of file +} 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 9716dfae23..c6848030cd 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 @@ -53,11 +53,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 +78,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); } @@ -101,13 +101,13 @@ public class NodeFilterValidator { 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); + validateStaticValueAndOperator(parentComponent, componentInstanceId, constraint); if (booleanResponseFormatEither.isRight()) { return booleanResponseFormatEither; } @@ -130,36 +130,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 +168,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 +188,48 @@ 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); } 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> isValidValueCheck(String type, String value, String propertyName) { @@ -237,16 +237,101 @@ 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, + final List<String> uiConstraints, + final NodeFilterConstraintAction action) { + try { + if (NodeFilterConstraintAction.ADD == action || NodeFilterConstraintAction.UPDATE == action) { + for (final String uiConstraint : uiConstraints) { + final UIConstraint constraint = new ConstraintConvertor().convert(uiConstraint); + if (ConstraintConvertor.PROPERTY_CONSTRAINT.equals(constraint.getSourceType())) { + final Either<Boolean, ResponseFormat> booleanResponseFormatEither = + validateComponentPropertyConstraint(component, constraint); + if (booleanResponseFormatEither.isRight()) { + return booleanResponseFormatEither; + } + } else if (ConstraintConvertor.STATIC_CONSTRAINT.equals(constraint.getSourceType())) { + final Either<Boolean, ResponseFormat> booleanResponseFormatEither = + validateComponentStaticValueAndOperator(component, constraint); + if (booleanResponseFormatEither.isRight()) { + return booleanResponseFormatEither; + } + } + } + } + } catch (final Exception e) { + LOGGER.debug("Provided constraint" + uiConstraints, e); + return Either.right(componentsUtils.getResponseFormat(ActionStatus.CONSTRAINT_FORMAT_INCORRECT)); + } -} + return Either.left(true); + } + private Either<Boolean, ResponseFormat> validateComponentPropertyConstraint(final Component component, + final UIConstraint uiConstraint) { + String source = SOURCE; + + final List<PropertyDefinition> propertyDefinitions = component.getProperties(); + List<? extends PropertyDefinition> sourcePropertyDefinition = + component.getName().equals(uiConstraint.getSourceName()) && + propertyDefinitions != null ? propertyDefinitions : Collections.emptyList(); + + if (!CollectionUtils.isEmpty(sourcePropertyDefinition)) { + final Optional<? extends PropertyDefinition> sourceSelectedProperty = sourcePropertyDefinition.stream() + .filter(property -> uiConstraint + .getValue() + .equals(property.getName())) + .findFirst(); + + final Optional<? extends PropertyDefinition> targetComponentProperty = + component.getProperties().stream() + .filter(property -> uiConstraint.getServicePropertyName().equals(property.getName())) + .findFirst(); + source = !targetComponentProperty.isPresent() ? "Target" : SOURCE; + if (sourceSelectedProperty.isPresent() && targetComponentProperty.isPresent()) { + return validatePropertyData(uiConstraint, sourceSelectedProperty, targetComponentProperty); + } + } + + final String missingProperty = + source.equals(SOURCE) ? uiConstraint.getValue().toString() : uiConstraint.getServicePropertyName(); + + return Either.right( + componentsUtils.getResponseFormat(ActionStatus.MAPPED_PROPERTY_NOT_FOUND, source, missingProperty)); + } + + private Either<Boolean, ResponseFormat> validateComponentStaticValueAndOperator( + final Component component, final UIConstraint uiConstraint) { + if (!(Objects.nonNull(uiConstraint) && uiConstraint.getValue() instanceof String)) { + return Either.left(false); + } + final Optional<PropertyDefinition> componentProperty = + component.getProperties().stream() + .filter(property -> uiConstraint.getServicePropertyName().equals(property.getName())) + .findFirst(); + + if (componentProperty.isEmpty()) { + return Either.right(componentsUtils.getResponseFormat(ActionStatus.SELECTED_PROPERTY_NOT_PRESENT, + uiConstraint.getServicePropertyName())); + } + if (comparableConstraintsOperators.contains(uiConstraint.getConstraintOperator()) && !comparableTypes.contains( + componentProperty.get().getType())) { + return Either.right(componentsUtils.getResponseFormat(ActionStatus.UNSUPPORTED_OPERATOR_PROVIDED, + uiConstraint.getServicePropertyName(), uiConstraint.getConstraintOperator())); + } + + return isValidValueCheck(componentProperty.get().getType(), String.valueOf(uiConstraint.getValue()), + uiConstraint.getServicePropertyName()); + } + +} diff --git a/catalog-be/src/main/java/org/openecomp/sdc/be/datamodel/utils/UiComponentDataConverter.java b/catalog-be/src/main/java/org/openecomp/sdc/be/datamodel/utils/UiComponentDataConverter.java index b3db99dc47..65c3b0e78e 100644 --- a/catalog-be/src/main/java/org/openecomp/sdc/be/datamodel/utils/UiComponentDataConverter.java +++ b/catalog-be/src/main/java/org/openecomp/sdc/be/datamodel/utils/UiComponentDataConverter.java @@ -50,6 +50,7 @@ import org.openecomp.sdc.be.model.Resource; import org.openecomp.sdc.be.model.Service; import org.openecomp.sdc.be.tosca.utils.NodeFilterConverter; import org.openecomp.sdc.be.tosca.utils.SubstitutionFilterConverter; +import org.openecomp.sdc.be.ui.model.UINodeFilter; import org.openecomp.sdc.be.ui.model.UiComponentDataTransfer; import org.openecomp.sdc.be.ui.model.UiComponentMetadata; import org.openecomp.sdc.be.ui.model.UiResourceDataTransfer; @@ -441,12 +442,14 @@ public class UiComponentDataConverter { } break; case SUBSTITUTION_FILTER: - if (service.getSubstitutionFilterComponents() == null) { + if (service.getSubstitutionFilter() == null) { dataTransfer.setSubstitutionFilterForTopologyTemplate(null); } else { final SubstitutionFilterConverter substitutionFilterConverter = new SubstitutionFilterConverter(); - dataTransfer.setSubstitutionFilterForTopologyTemplate(substitutionFilterConverter - .convertDataMapToUI(service.getSubstitutionFilterComponents())); + final Map<String, UINodeFilter> filterUiMap = new HashMap<>(); + filterUiMap.put(service.getUniqueId(), + substitutionFilterConverter.convertToUi(service.getSubstitutionFilter())); + dataTransfer.setSubstitutionFilterForTopologyTemplate(filterUiMap); } break; default: diff --git a/catalog-be/src/main/java/org/openecomp/sdc/be/servlets/ComponentSubstitutionFilterServlet.java b/catalog-be/src/main/java/org/openecomp/sdc/be/servlets/ComponentSubstitutionFilterServlet.java index b451b33fb9..4a44c202f3 100644 --- a/catalog-be/src/main/java/org/openecomp/sdc/be/servlets/ComponentSubstitutionFilterServlet.java +++ b/catalog-be/src/main/java/org/openecomp/sdc/be/servlets/ComponentSubstitutionFilterServlet.java @@ -47,12 +47,12 @@ import org.openecomp.sdc.be.components.impl.ComponentSubstitutionFilterBusinessL import org.openecomp.sdc.be.components.impl.ResourceImportManager; import org.openecomp.sdc.be.components.impl.aaf.AafPermission; import org.openecomp.sdc.be.components.impl.aaf.PermissionAllowed; -import org.openecomp.sdc.be.components.impl.utils.NodeFilterConstraintAction; import org.openecomp.sdc.be.config.BeEcompErrorManager; import org.openecomp.sdc.be.dao.api.ActionStatus; import org.openecomp.sdc.be.datamodel.utils.ConstraintConvertor; import org.openecomp.sdc.be.datatypes.elements.SubstitutionFilterDataDefinition; import org.openecomp.sdc.be.datatypes.enums.ComponentTypeEnum; +import org.openecomp.sdc.be.datatypes.enums.NodeFilterConstraintType; import org.openecomp.sdc.be.impl.ComponentsUtils; import org.openecomp.sdc.be.impl.ServletUtils; import org.openecomp.sdc.be.model.User; @@ -64,7 +64,7 @@ import org.openecomp.sdc.common.api.Constants; import org.slf4j.Logger; import org.slf4j.LoggerFactory; -@Path("/v1/catalog/{componentType}/{componentId}/resourceInstances/{componentInstanceId}/substitutionFilter") +@Path("/v1/catalog/{componentType}/{componentId}/substitutionFilter/{constraintType}") @Consumes(MediaType.APPLICATION_JSON) @Produces(MediaType.APPLICATION_JSON) @Singleton @@ -74,6 +74,7 @@ public class ComponentSubstitutionFilterServlet extends AbstractValidationsServl 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"; + private static final String INVALID_CONSTRAINTYPE_ENUM = "Invalid value for NodeFilterConstraintType enum %s"; private static final String FAILED_TO_ADD_SUBSTITUTION_FILTER = "Failed to add substitution filter"; private static final String ADD_SUBSTITUTION_FILTER = "Add Substitution Filter"; @@ -103,7 +104,6 @@ public class ComponentSubstitutionFilterServlet extends AbstractValidationsServl @POST @Consumes(MediaType.APPLICATION_JSON) @Produces(MediaType.APPLICATION_JSON) - @Path("/") @Operation(description = "Add Component Substitution Filter Constraint", method = "POST", summary = "Add Component Substitution Filter Constraint", responses = { @ApiResponse(content = @Content(array = @ArraySchema(schema = @Schema(implementation = Response.class)))), @@ -114,10 +114,14 @@ public class ComponentSubstitutionFilterServlet extends AbstractValidationsServl public Response addSubstitutionFilter( @Parameter(description = "UIConstraint data", required = true) String constraintData, @Parameter(description = "Component Id") @PathParam("componentId") String componentId, - @Parameter(description = "Component Instance Id") @PathParam("componentInstanceId") String componentInstanceId, - @Parameter(description = "valid value: services", + @Parameter(description = "valid value: resources / services", schema = @Schema(allowableValues = { + ComponentTypeEnum.SERVICE_PARAM_NAME, ComponentTypeEnum.SERVICE_PARAM_NAME})) @PathParam("componentType") final String componentType, + @Parameter(description = "Constraint type. Valid values: properties / capabilities", + schema = @Schema(allowableValues = {NodeFilterConstraintType.PROPERTIES_PARAM_NAME, + NodeFilterConstraintType.CAPABILITIES_PARAM_NAME})) + @PathParam("constraintType") final String constraintType, @Context final HttpServletRequest request, @HeaderParam(value = Constants.USER_ID_HEADER) String userId) { @@ -129,28 +133,26 @@ public class ComponentSubstitutionFilterServlet extends AbstractValidationsServl 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 Optional<SubstitutionFilterDataDefinition> substitutionFilter = - componentSubstitutionFilterBusinessLogic.createSubstitutionFilterIfNotExist(componentId, - componentInstanceId, true, componentTypeEnum); - if (!substitutionFilter.isPresent()) { - LOGGER.error("Failed to create substitution filter."); - BeEcompErrorManager.getInstance().logBeRestApiGeneralError(ADD_SUBSTITUTION_FILTER); - 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.isEmpty()) { + return buildErrorResponse(getComponentsUtils().getResponseFormat(ActionStatus.INVALID_CONTENT_PARAM, + INVALID_CONSTRAINTYPE_ENUM, constraintType)); + } + final Optional<SubstitutionFilterDataDefinition> actionResponse = componentSubstitutionFilterBusinessLogic - .addSubstitutionFilter(componentId.toLowerCase(), componentInstanceId, NodeFilterConstraintAction.ADD, + .addSubstitutionFilter(componentId.toLowerCase(), uiConstraint.getServicePropertyName(), constraint, true, componentTypeEnum); - if (!actionResponse.isPresent()) { + if (actionResponse.isEmpty()) { LOGGER.error(FAILED_TO_ADD_SUBSTITUTION_FILTER); return buildErrorResponse(getComponentsUtils().getResponseFormat(ActionStatus.GENERAL_ERROR)); } @@ -168,7 +170,6 @@ public class ComponentSubstitutionFilterServlet extends AbstractValidationsServl @PUT @Consumes(MediaType.APPLICATION_JSON) @Produces(MediaType.APPLICATION_JSON) - @Path("/") @Operation(description = "Update Component Substitution Filter Constraint", method = "PUT", summary = "Update Component Substitution Filter Constraint", responses = { @ApiResponse(content = @Content(array = @ArraySchema(schema = @Schema(implementation = Response.class)))), @@ -179,10 +180,14 @@ public class ComponentSubstitutionFilterServlet extends AbstractValidationsServl public Response updateSubstitutionFilter( @Parameter(description = "UIConstraint data", required = true) String constraintData, @Parameter(description = "Component Id") @PathParam("componentId") String componentId, - @Parameter(description = "Component Instance Id") @PathParam("componentInstanceId") String componentInstanceId, - @Parameter(description = "valid value: services", + @Parameter(description = "valid value: resources / services", schema = @Schema(allowableValues = { + ComponentTypeEnum.SERVICE_PARAM_NAME, ComponentTypeEnum.SERVICE_PARAM_NAME})) @PathParam("componentType") final String componentType, + @Parameter(description = "Constraint type. Valid values: properties / capabilities", + schema = @Schema(allowableValues = {NodeFilterConstraintType.PROPERTIES_PARAM_NAME, + NodeFilterConstraintType.CAPABILITIES_PARAM_NAME})) + @PathParam("constraintType") final String constraintType, @Context final HttpServletRequest request, @HeaderParam(value = Constants.USER_ID_HEADER) String userId) { LOGGER.debug(START_HANDLE_REQUEST_OF, request.getMethod(), request.getRequestURI()); @@ -201,8 +206,14 @@ public class ComponentSubstitutionFilterServlet extends AbstractValidationsServl } final List<String> constraints = new ConstraintConvertor().convertToList(uiConstraints); + final Optional<NodeFilterConstraintType> nodeFilterConstraintType = + NodeFilterConstraintType.parse(constraintType); + if (!nodeFilterConstraintType.isPresent()) { + return buildErrorResponse(getComponentsUtils().getResponseFormat(ActionStatus.INVALID_CONTENT_PARAM, + INVALID_CONSTRAINTYPE_ENUM, constraintType)); + } final Optional<SubstitutionFilterDataDefinition> actionResponse = componentSubstitutionFilterBusinessLogic - .updateSubstitutionFilter(componentId.toLowerCase(), componentInstanceId, constraints, + .updateSubstitutionFilter(componentId.toLowerCase(), constraints, true, componentTypeEnum); if (!actionResponse.isPresent()) { @@ -233,22 +244,31 @@ public class ComponentSubstitutionFilterServlet extends AbstractValidationsServl @PermissionAllowed(AafPermission.PermNames.INTERNAL_ALL_VALUE) public Response deleteSubstitutionFilterConstraint( @Parameter(description = "Component Id") @PathParam("componentId") String componentId, - @Parameter(description = "Component Instance Id") @PathParam("componentInstanceId") String componentInstanceId, @Parameter(description = "Constraint Index") @PathParam("constraintIndex") int index, - @Parameter(description = "valid value: services", + @Parameter(description = "valid value: resources / services", schema = @Schema(allowableValues = { + ComponentTypeEnum.SERVICE_PARAM_NAME, ComponentTypeEnum.SERVICE_PARAM_NAME})) @PathParam("componentType") final String componentType, + @Parameter(description = "Constraint type. Valid values: properties / capabilities", + schema = @Schema(allowableValues = {NodeFilterConstraintType.PROPERTIES_PARAM_NAME, + NodeFilterConstraintType.CAPABILITIES_PARAM_NAME})) + @PathParam("constraintType") final String constraintType, @Context final HttpServletRequest request, @HeaderParam(value = Constants.USER_ID_HEADER) String userId) { LOGGER.debug(START_HANDLE_REQUEST_OF, request.getMethod(), request.getRequestURI()); LOGGER.debug(MODIFIER_ID_IS, userId); componentSubstitutionFilterBusinessLogic.validateUser(userId); + final Optional<NodeFilterConstraintType> nodeFilterConstraintType = + NodeFilterConstraintType.parse(constraintType); + if (!nodeFilterConstraintType.isPresent()) { + return buildErrorResponse(getComponentsUtils().getResponseFormat(ActionStatus.INVALID_CONTENT_PARAM, + INVALID_CONSTRAINTYPE_ENUM, constraintType)); + } + try { final Optional<SubstitutionFilterDataDefinition> actionResponse = componentSubstitutionFilterBusinessLogic - .deleteSubstitutionFilter(componentId.toLowerCase(), componentInstanceId, - NodeFilterConstraintAction.DELETE, - null, index, true, ComponentTypeEnum.findByParamName(componentType)); + .deleteSubstitutionFilter(componentId.toLowerCase(), index, true, ComponentTypeEnum.findByParamName(componentType)); if (!actionResponse.isPresent()) { LOGGER.debug(FAILED_TO_DELETE_SUBSTITUTION_FILTER); diff --git a/catalog-be/src/main/java/org/openecomp/sdc/be/tosca/ToscaExportHandler.java b/catalog-be/src/main/java/org/openecomp/sdc/be/tosca/ToscaExportHandler.java index 533ed7a6f0..0907dd1f9b 100644 --- a/catalog-be/src/main/java/org/openecomp/sdc/be/tosca/ToscaExportHandler.java +++ b/catalog-be/src/main/java/org/openecomp/sdc/be/tosca/ToscaExportHandler.java @@ -57,6 +57,7 @@ import org.openecomp.sdc.be.datatypes.elements.ListDataDefinition; import org.openecomp.sdc.be.datatypes.elements.PropertyDataDefinition; import org.openecomp.sdc.be.datatypes.elements.RequirementNodeFilterCapabilityDataDefinition; import org.openecomp.sdc.be.datatypes.elements.RequirementNodeFilterPropertyDataDefinition; +import org.openecomp.sdc.be.datatypes.elements.RequirementSubstitutionFilterCapabilityDataDefinition; import org.openecomp.sdc.be.datatypes.elements.RequirementSubstitutionFilterPropertyDataDefinition; import org.openecomp.sdc.be.datatypes.elements.SubstitutionFilterDataDefinition; import org.openecomp.sdc.be.datatypes.elements.ToscaArtifactDataDefinition; @@ -314,7 +315,6 @@ public class ToscaExportHandler { component.getComponentInstancesProperties(); Map<String, List<ComponentInstanceInterface>> componentInstanceInterfaces = component.getComponentInstancesInterfaces(); - SubstitutionMapping substitutionMapping = new SubstitutionMapping(); if (CollectionUtils.isNotEmpty(componentInstances)) { final Either<Map<String, ToscaNodeTemplate>, ToscaError> nodeTemplates = convertNodeTemplates(component, componentInstances, @@ -325,10 +325,11 @@ public class ToscaExportHandler { } log.debug("node templates converted"); topologyTemplate.setNode_templates(nodeTemplates.left().value()); - - convertSubstitutionMappingFilter(componentInstances, substitutionMapping); } + SubstitutionMapping substitutionMapping = new SubstitutionMapping(); + convertSubstitutionMappingFilter(component, substitutionMapping); + addGroupsToTopologyTemplate(component, topologyTemplate); try { @@ -377,19 +378,13 @@ public class ToscaExportHandler { return Either.left(toscaNode); } - private void convertSubstitutionMappingFilter(final List<ComponentInstance> componentInstances, + private void convertSubstitutionMappingFilter(final Component component, final SubstitutionMapping substitutionMapping) { - componentInstances.stream() - .filter(componentInstance -> hasSubstitutionFilterDataDefinition(componentInstance.getSubstitutionFilter())) - .forEach(componentInstance -> substitutionMapping - .setSubstitution_filter(convertToSubstitutionFilterComponent(componentInstance.getSubstitutionFilter()))); - } - - private boolean hasSubstitutionFilterDataDefinition( - final SubstitutionFilterDataDefinition substitutionFilterDataDefinition) { - - return substitutionFilterDataDefinition != null && substitutionFilterDataDefinition.getProperties() != null - && CollectionUtils.isNotEmpty(substitutionFilterDataDefinition.getProperties().getListToscaDataDefinition()); + if(component.getSubstitutionFilter() != null + && (component.getSubstitutionFilter().getProperties()).getListToscaDataDefinition() != null) { + substitutionMapping + .setSubstitution_filter(convertToSubstitutionFilterComponent(component.getSubstitutionFilter())); + } } private void addGroupsToTopologyTemplate(Component component, ToscaTopolgyTemplate topologyTemplate) { @@ -1521,18 +1516,23 @@ public class ToscaExportHandler { private NodeFilter convertToSubstitutionFilterComponent( final SubstitutionFilterDataDefinition substitutionFilterDataDefinition) { + if (substitutionFilterDataDefinition == null) { + return null; + } NodeFilter nodeFilter = new NodeFilter(); - final List<Map<String, List<Object>>> propertiesCopy = new ArrayList<>(); - copySubstitutionFilterProperties(substitutionFilterDataDefinition.getProperties(), propertiesCopy); + ListDataDefinition<RequirementSubstitutionFilterPropertyDataDefinition> origProperties = + substitutionFilterDataDefinition.getProperties(); + List<Map<String, List<Object>>> propertiesCopy = new ArrayList<>(); + + copySubstitutionFilterProperties(origProperties, propertiesCopy); if (CollectionUtils.isNotEmpty(propertiesCopy)) { nodeFilter.setProperties(propertiesCopy); } nodeFilter.setTosca_id(cloneToscaId(substitutionFilterDataDefinition.getTosca_id())); - nodeFilter = (NodeFilter) cloneObjectFromYml(nodeFilter, NodeFilter.class); - return nodeFilter; + return (NodeFilter) cloneObjectFromYml(nodeFilter, NodeFilter.class); } private Object cloneToscaId(Object toscaId) { diff --git a/catalog-be/src/main/java/org/openecomp/sdc/be/tosca/utils/SubstitutionFilterConverter.java b/catalog-be/src/main/java/org/openecomp/sdc/be/tosca/utils/SubstitutionFilterConverter.java index 326ebf3709..d43ba4334c 100644 --- a/catalog-be/src/main/java/org/openecomp/sdc/be/tosca/utils/SubstitutionFilterConverter.java +++ b/catalog-be/src/main/java/org/openecomp/sdc/be/tosca/utils/SubstitutionFilterConverter.java @@ -19,32 +19,68 @@ package org.openecomp.sdc.be.tosca.utils; +import java.util.Collections; import java.util.List; -import java.util.Map; import java.util.stream.Collectors; +import org.apache.commons.collections.CollectionUtils; import org.openecomp.sdc.be.datamodel.utils.ConstraintConvertor; +import org.openecomp.sdc.be.datatypes.elements.ListDataDefinition; +import org.openecomp.sdc.be.datatypes.elements.RequirementSubstitutionFilterCapabilityDataDefinition; +import org.openecomp.sdc.be.datatypes.elements.RequirementSubstitutionFilterPropertyDataDefinition; import org.openecomp.sdc.be.datatypes.elements.SubstitutionFilterDataDefinition; import org.openecomp.sdc.be.ui.model.UIConstraint; import org.openecomp.sdc.be.ui.model.UINodeFilter; public class SubstitutionFilterConverter { - public Map<String, UINodeFilter> convertDataMapToUI(Map<String, SubstitutionFilterDataDefinition> inMap) { - return inMap.entrySet().stream().collect(Collectors.toMap(Map.Entry::getKey, o -> convertToUi(o.getValue()))); - } - public UINodeFilter convertToUi(final SubstitutionFilterDataDefinition inSubstitutionFilter) { final UINodeFilter uiNodeFilter = new UINodeFilter(); final ConstraintConvertor constraintConvertor = new ConstraintConvertor(); - if (inSubstitutionFilter.getProperties() == null || inSubstitutionFilter.getProperties().isEmpty()) { - return uiNodeFilter; + final List<UIConstraint> uiPropertyFilters = extractPropertyFilter(inSubstitutionFilter, constraintConvertor); + if (!uiPropertyFilters.isEmpty()) { + uiNodeFilter.setProperties(uiPropertyFilters); + } + + final List<UIConstraint> uiCapabilityFilters = + extractCapabilitiesFilter(inSubstitutionFilter, constraintConvertor); + if (!uiCapabilityFilters.isEmpty()) { + uiNodeFilter.setCapabilities(uiCapabilityFilters); } - final List<UIConstraint> constraints = inSubstitutionFilter.getProperties().getListToscaDataDefinition() - .stream() - .map(property -> property.getConstraints().iterator().next()) - .map(constraintConvertor::convert) - .collect(Collectors.toList()); - uiNodeFilter.setProperties(constraints); + return uiNodeFilter; } + + private List<UIConstraint> extractPropertyFilter(final SubstitutionFilterDataDefinition substitutionFilter, + final ConstraintConvertor constraintConvertor) { + final ListDataDefinition<RequirementSubstitutionFilterPropertyDataDefinition> substitutionFilterProperties = + substitutionFilter.getProperties(); + if (substitutionFilterProperties != null && !substitutionFilterProperties.isEmpty() + && CollectionUtils.isNotEmpty(substitutionFilterProperties.getListToscaDataDefinition())) { + return substitutionFilterProperties.getListToscaDataDefinition() + .stream() + .map(property -> property.getConstraints().iterator().next()) + .map(constraintConvertor::convert) + .collect(Collectors.toList()); + } + + return Collections.emptyList(); + } + + private List<UIConstraint> extractCapabilitiesFilter(final SubstitutionFilterDataDefinition substitutionFilter, + final ConstraintConvertor constraintConvertor) { + final ListDataDefinition<RequirementSubstitutionFilterCapabilityDataDefinition> substitutionFilterCapabilities = + substitutionFilter.getCapabilities(); + if (substitutionFilterCapabilities != null && !substitutionFilterCapabilities.isEmpty() + && CollectionUtils.isNotEmpty(substitutionFilterCapabilities.getListToscaDataDefinition())) { + return substitutionFilterCapabilities + .getListToscaDataDefinition() + .stream() + .map(capabilities -> capabilities.getProperties().getListToscaDataDefinition().iterator().next()) + .map(property -> property.getConstraints().iterator().next()) + .map(constraintConvertor::convert) + .collect(Collectors.toList()); + } + + return Collections.emptyList(); + } } diff --git a/catalog-be/src/test/java/org/openecomp/sdc/be/components/impl/ComponentSubstitutionFilterBusinessLogicTest.java b/catalog-be/src/test/java/org/openecomp/sdc/be/components/impl/ComponentSubstitutionFilterBusinessLogicTest.java index eaeb5ea11a..666d1e7f39 100644 --- a/catalog-be/src/test/java/org/openecomp/sdc/be/components/impl/ComponentSubstitutionFilterBusinessLogicTest.java +++ b/catalog-be/src/test/java/org/openecomp/sdc/be/components/impl/ComponentSubstitutionFilterBusinessLogicTest.java @@ -19,7 +19,6 @@ package org.openecomp.sdc.be.components.impl; -import static java.util.Collections.singletonList; import static org.assertj.core.api.Assertions.assertThat; import static org.junit.jupiter.api.Assertions.assertThrows; import static org.junit.jupiter.api.Assertions.fail; @@ -32,14 +31,12 @@ import static org.mockito.Mockito.verify; import static org.mockito.Mockito.when; import fj.data.Either; -import java.util.ArrayList; import java.util.Arrays; import java.util.Collections; -import java.util.HashMap; import java.util.LinkedList; import java.util.List; -import java.util.Map; import java.util.Optional; + import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; import org.junit.jupiter.api.extension.ExtendWith; @@ -51,8 +48,6 @@ import org.openecomp.sdc.be.components.impl.exceptions.BusinessLogicException; import org.openecomp.sdc.be.components.impl.utils.NodeFilterConstraintAction; import org.openecomp.sdc.be.components.validation.NodeFilterValidator; import org.openecomp.sdc.be.components.validation.UserValidations; -import org.openecomp.sdc.be.config.ConfigurationManager; -import org.openecomp.sdc.be.dao.api.ActionStatus; import org.openecomp.sdc.be.dao.janusgraph.JanusGraphGenericDao; import org.openecomp.sdc.be.dao.jsongraph.JanusGraphDao; import org.openecomp.sdc.be.datamodel.utils.ConstraintConvertor; @@ -62,16 +57,13 @@ import org.openecomp.sdc.be.datatypes.elements.SubstitutionFilterDataDefinition; import org.openecomp.sdc.be.datatypes.enums.ComponentTypeEnum; import org.openecomp.sdc.be.datatypes.enums.NodeTypeEnum; import org.openecomp.sdc.be.impl.ComponentsUtils; -import org.openecomp.sdc.be.model.ComponentInstance; -import org.openecomp.sdc.be.model.ComponentInstanceProperty; -import org.openecomp.sdc.be.model.PropertyDefinition; import org.openecomp.sdc.be.model.Service; +import org.openecomp.sdc.be.model.PropertyDefinition; import org.openecomp.sdc.be.model.jsonjanusgraph.operations.SubstitutionFilterOperation; import org.openecomp.sdc.be.model.jsonjanusgraph.operations.ToscaOperationFacade; import org.openecomp.sdc.be.model.operations.api.StorageOperationStatus; import org.openecomp.sdc.be.model.operations.impl.GraphLockOperation; import org.openecomp.sdc.be.ui.model.UIConstraint; -import org.openecomp.sdc.exception.ResponseFormat; @ExtendWith(MockitoExtension.class) public class ComponentSubstitutionFilterBusinessLogicTest extends BaseBusinessLogicMock { @@ -82,13 +74,10 @@ public class ComponentSubstitutionFilterBusinessLogicTest extends BaseBusinessLo private static final String sourceName = sourceType; private static final String propertyValue = "constraintValue"; private static final String componentId = "dac65869-dfb4-40d2-aa20-084324659ec1"; - private static final String componentInstanceId = "dac65869-dfb4-40d2-aa20-084324659ec1.service0"; @InjectMocks private ComponentSubstitutionFilterBusinessLogic componentSubstitutionFilterBusinessLogic; @Mock - private NodeFilterValidator nodeFilterValidator; - @Mock private SubstitutionFilterOperation substitutionFilterOperation; @Mock private ToscaOperationFacade toscaOperationFacade; @@ -103,10 +92,9 @@ public class ComponentSubstitutionFilterBusinessLogicTest extends BaseBusinessLo @Mock private UserValidations userValidations; @Mock - private ResponseFormat responseFormat; + private NodeFilterValidator nodeFilterValidator; private Service service; - private ComponentInstance componentInstance; private SubstitutionFilterDataDefinition substitutionFilterDataDefinition; private RequirementSubstitutionFilterPropertyDataDefinition requirementSubstitutionFilterPropertyDataDefinition; private String constraint; @@ -130,12 +118,12 @@ public class ComponentSubstitutionFilterBusinessLogicTest extends BaseBusinessLo @Test public void doNotCreateSubstitutionFilterAsExistsTest() throws BusinessLogicException { - componentInstance.setSubstitutionFilter(substitutionFilterDataDefinition); + service.setSubstitutionFilter(substitutionFilterDataDefinition); when(toscaOperationFacade.getToscaElement(componentId)).thenReturn(Either.left(service)); final Optional<SubstitutionFilterDataDefinition> result = componentSubstitutionFilterBusinessLogic - .createSubstitutionFilterIfNotExist(componentId, componentInstanceId, true, ComponentTypeEnum.SERVICE); + .createSubstitutionFilterIfNotExist(componentId, true, ComponentTypeEnum.SERVICE); assertThat(result).isPresent(); assertThat(result.get().getProperties()).isEqualTo(substitutionFilterDataDefinition.getProperties()); verify(toscaOperationFacade, times(1)).getToscaElement(componentId); @@ -145,19 +133,19 @@ public class ComponentSubstitutionFilterBusinessLogicTest extends BaseBusinessLo public void createSubstitutionFilterIfNotExistTest() throws BusinessLogicException { when(toscaOperationFacade.getToscaElement(componentId)).thenReturn(Either.left(service)); when(graphLockOperation.lockComponent(componentId, NodeTypeEnum.Service)) - .thenReturn(StorageOperationStatus.OK); - when(substitutionFilterOperation.createSubstitutionFilter(componentId, componentInstanceId)) - .thenReturn(Either.left(substitutionFilterDataDefinition)); + .thenReturn(StorageOperationStatus.OK); + when(substitutionFilterOperation.createSubstitutionFilter(componentId)) + .thenReturn(Either.left(substitutionFilterDataDefinition)); when(graphLockOperation.unlockComponent(componentId, NodeTypeEnum.Service)) - .thenReturn(StorageOperationStatus.OK); + .thenReturn(StorageOperationStatus.OK); final Optional<SubstitutionFilterDataDefinition> result = componentSubstitutionFilterBusinessLogic - .createSubstitutionFilterIfNotExist(componentId, componentInstanceId, true, ComponentTypeEnum.SERVICE); + .createSubstitutionFilterIfNotExist(componentId, true, ComponentTypeEnum.SERVICE); assertThat(result).isPresent(); assertThat(result.get().getProperties()).isEqualTo(substitutionFilterDataDefinition.getProperties()); verify(toscaOperationFacade, times(1)).getToscaElement(componentId); verify(graphLockOperation, times(1)).lockComponent(componentId, NodeTypeEnum.Service); - verify(substitutionFilterOperation, times(1)).createSubstitutionFilter(componentId, componentInstanceId); + verify(substitutionFilterOperation, times(1)).createSubstitutionFilter(componentId); verify(graphLockOperation, times(1)).unlockComponent(componentId, NodeTypeEnum.Service); } @@ -165,283 +153,191 @@ public class ComponentSubstitutionFilterBusinessLogicTest extends BaseBusinessLo public void createSubstitutionFilterIfNotExistFailTest() { when(toscaOperationFacade.getToscaElement(componentId)).thenReturn(Either.left(service)); when(graphLockOperation.lockComponent(componentId, NodeTypeEnum.Service)) - .thenReturn(StorageOperationStatus.OK); - when(substitutionFilterOperation.createSubstitutionFilter(componentId, componentInstanceId)) - .thenReturn(Either.right(StorageOperationStatus.GENERAL_ERROR)); + .thenReturn(StorageOperationStatus.OK); + when(substitutionFilterOperation.createSubstitutionFilter(componentId)) + .thenReturn(Either.right(StorageOperationStatus.GENERAL_ERROR)); when(graphLockOperation.unlockComponent(componentId, NodeTypeEnum.Service)) - .thenReturn(StorageOperationStatus.OK); + .thenReturn(StorageOperationStatus.OK); assertThrows(BusinessLogicException.class, () -> componentSubstitutionFilterBusinessLogic - .createSubstitutionFilterIfNotExist(componentId, componentInstanceId, true, ComponentTypeEnum.SERVICE)); + .createSubstitutionFilterIfNotExist(componentId, true, ComponentTypeEnum.SERVICE)); verify(toscaOperationFacade, times(1)).getToscaElement(componentId); verify(graphLockOperation, times(1)).lockComponent(componentId, NodeTypeEnum.Service); - verify(substitutionFilterOperation, times(1)).createSubstitutionFilter(componentId, componentInstanceId); + verify(substitutionFilterOperation, times(1)).createSubstitutionFilter(componentId); verify(graphLockOperation, times(1)).unlockComponent(componentId, NodeTypeEnum.Service); } @Test public void addSubstitutionFilterTest() throws BusinessLogicException { - componentInstance.setSubstitutionFilter(substitutionFilterDataDefinition); + service.setSubstitutionFilter(substitutionFilterDataDefinition); when(toscaOperationFacade.getToscaElement(componentId)).thenReturn(Either.left(service)); - when(nodeFilterValidator.validateFilter(service, componentInstanceId, Collections.singletonList(constraint), - NodeFilterConstraintAction.ADD)).thenReturn(Either.left(true)); - when(nodeFilterValidator.validateComponentInstanceExist(service, componentInstanceId)) - .thenReturn(Either.left(true)); when(graphLockOperation.lockComponent(componentId, NodeTypeEnum.Service)) .thenReturn(StorageOperationStatus.OK); - + when(nodeFilterValidator.validateComponentFilter(service, Collections.singletonList(constraint), + NodeFilterConstraintAction.ADD)).thenReturn(Either.left(true)); when(substitutionFilterOperation - .addNewProperty(anyString(), anyString(), any(SubstitutionFilterDataDefinition.class), + .addPropertyFilter(anyString(), any(SubstitutionFilterDataDefinition.class), any(RequirementSubstitutionFilterPropertyDataDefinition.class))) .thenReturn(Either.left(substitutionFilterDataDefinition)); - when(graphLockOperation.unlockComponent(componentId, NodeTypeEnum.Service)) .thenReturn(StorageOperationStatus.OK); final Optional<SubstitutionFilterDataDefinition> result = componentSubstitutionFilterBusinessLogic - .addSubstitutionFilter(componentId, componentInstanceId, NodeFilterConstraintAction.ADD, - servicePropertyName, constraint, true, ComponentTypeEnum.SERVICE); + .addSubstitutionFilter(componentId, servicePropertyName, constraint, true, + ComponentTypeEnum.SERVICE); assertThat(result).isPresent(); assertThat(result.get().getProperties().getListToscaDataDefinition()).hasSize(1); verify(toscaOperationFacade, times(1)).getToscaElement(componentId); verify(graphLockOperation, times(1)).lockComponent(componentId, NodeTypeEnum.Service); - verify(nodeFilterValidator, times(1)).validateFilter(service, componentInstanceId, - Collections.singletonList(constraint), NodeFilterConstraintAction.ADD); - verify(substitutionFilterOperation, times(0)) - .addNewProperty(componentId, componentInstanceId, substitutionFilterDataDefinition, - requirementSubstitutionFilterPropertyDataDefinition); + verify(nodeFilterValidator, times(1)).validateComponentFilter(service, + Collections.singletonList(constraint), NodeFilterConstraintAction.ADD); + verify(substitutionFilterOperation, times(1)) + .addPropertyFilter(anyString(), any(SubstitutionFilterDataDefinition.class), + any(RequirementSubstitutionFilterPropertyDataDefinition.class)); verify(graphLockOperation, times(1)).unlockComponent(componentId, NodeTypeEnum.Service); } @Test public void addSubstitutionFilterFailTest() { - componentInstance.setSubstitutionFilter(substitutionFilterDataDefinition); + service.setSubstitutionFilter(substitutionFilterDataDefinition); when(toscaOperationFacade.getToscaElement(componentId)).thenReturn(Either.left(service)); - when(nodeFilterValidator.validateFilter(service, componentInstanceId, Collections.singletonList(constraint), - NodeFilterConstraintAction.ADD)).thenReturn(Either.left(true)); - when(nodeFilterValidator.validateComponentInstanceExist(service, componentInstanceId)) - .thenReturn(Either.left(true)); when(graphLockOperation.lockComponent(componentId, NodeTypeEnum.Service)) .thenReturn(StorageOperationStatus.OK); - + when(nodeFilterValidator.validateComponentFilter(service, Collections.singletonList(constraint), + NodeFilterConstraintAction.ADD)).thenReturn(Either.left(true)); when(substitutionFilterOperation - .addNewProperty(anyString(), anyString(), any(SubstitutionFilterDataDefinition.class), - any(RequirementSubstitutionFilterPropertyDataDefinition.class))) + .addPropertyFilter(componentId, substitutionFilterDataDefinition, + requirementSubstitutionFilterPropertyDataDefinition)) .thenReturn(Either.right(StorageOperationStatus.GENERAL_ERROR)); when(graphLockOperation.unlockComponent(componentId, NodeTypeEnum.Service)) .thenReturn(StorageOperationStatus.OK); assertThrows(BusinessLogicException.class, () -> componentSubstitutionFilterBusinessLogic - .addSubstitutionFilter(componentId, componentInstanceId, NodeFilterConstraintAction.ADD, - servicePropertyName, constraint, true, ComponentTypeEnum.SERVICE)); + .addSubstitutionFilter(componentId, servicePropertyName, constraint, true, + ComponentTypeEnum.SERVICE)); verify(toscaOperationFacade, times(1)).getToscaElement(componentId); verify(graphLockOperation, times(1)).lockComponent(componentId, NodeTypeEnum.Service); - verify(nodeFilterValidator, times(1)).validateFilter(service, componentInstanceId, - Collections.singletonList(constraint), NodeFilterConstraintAction.ADD); + verify(nodeFilterValidator, times(1)).validateComponentFilter(service, + Collections.singletonList(constraint), NodeFilterConstraintAction.ADD); verify(substitutionFilterOperation, times(0)) - .addNewProperty(componentId, componentInstanceId, substitutionFilterDataDefinition, + .addPropertyFilter(componentId, substitutionFilterDataDefinition, requirementSubstitutionFilterPropertyDataDefinition); verify(graphLockOperation, times(1)).unlockComponent(componentId, NodeTypeEnum.Service); } @Test public void updateSubstitutionFilterTest() throws BusinessLogicException { - componentInstance.setSubstitutionFilter(substitutionFilterDataDefinition); + service.setSubstitutionFilter(substitutionFilterDataDefinition); + final List<String> constraints = requirementSubstitutionFilterPropertyDataDefinition.getConstraints(); when(toscaOperationFacade.getToscaElement(componentId)).thenReturn(Either.left(service)); - when(nodeFilterValidator.validateFilter(service, componentInstanceId, - Collections.singletonList(constraint), NodeFilterConstraintAction.UPDATE)).thenReturn(Either.left(true)); when(graphLockOperation.lockComponent(componentId, NodeTypeEnum.Service)) .thenReturn(StorageOperationStatus.OK); - - when(substitutionFilterOperation.updateSubstitutionFilter(anyString(), anyString(), - any(SubstitutionFilterDataDefinition.class), anyList())) - .thenReturn(Either.left(substitutionFilterDataDefinition)); - + when(nodeFilterValidator.validateComponentFilter(service, Collections.singletonList(constraint), + NodeFilterConstraintAction.UPDATE)).thenReturn(Either.left(true)); + when(substitutionFilterOperation.updateProperties(anyString(), any(SubstitutionFilterDataDefinition.class), anyList())) + .thenReturn(Either.left(substitutionFilterDataDefinition)); when(graphLockOperation.unlockComponent(componentId, NodeTypeEnum.Service)) .thenReturn(StorageOperationStatus.OK); final Optional<SubstitutionFilterDataDefinition> result = componentSubstitutionFilterBusinessLogic - .updateSubstitutionFilter(componentId, componentInstanceId, Collections.singletonList(constraint), + .updateSubstitutionFilter(componentId, Collections.singletonList(constraint), true, ComponentTypeEnum.SERVICE); assertThat(result).isPresent(); - + assertThat(result.get().getProperties().getListToscaDataDefinition()).hasSize(1); + verify(substitutionFilterOperation, times(1)) + .updateProperties(anyString(), any(SubstitutionFilterDataDefinition.class), anyList()); + verify(nodeFilterValidator, times(1)).validateComponentFilter(service, + Collections.singletonList(constraint), NodeFilterConstraintAction.UPDATE); verify(toscaOperationFacade, times(1)).getToscaElement(componentId); - verify(nodeFilterValidator, times(1)).validateFilter(service, componentInstanceId, - Collections.singletonList(constraint), NodeFilterConstraintAction.UPDATE); + verify(graphLockOperation, times(1)).lockComponent(componentId, NodeTypeEnum.Service); + verify(graphLockOperation, times(1)).unlockComponent(componentId, NodeTypeEnum.Service); } @Test public void updateSubstitutionFilterFailTest() { - componentInstance.setSubstitutionFilter(substitutionFilterDataDefinition); + service.setSubstitutionFilter(substitutionFilterDataDefinition); when(toscaOperationFacade.getToscaElement(componentId)).thenReturn(Either.left(service)); - when(nodeFilterValidator.validateFilter(service, componentInstanceId, - Collections.singletonList(constraint), NodeFilterConstraintAction.UPDATE)).thenReturn(Either.left(true)); when(graphLockOperation.lockComponent(componentId, NodeTypeEnum.Service)) .thenReturn(StorageOperationStatus.OK); - - when(substitutionFilterOperation.updateSubstitutionFilter(anyString(), anyString(), - any(SubstitutionFilterDataDefinition.class), anyList())) - .thenReturn(Either.right(StorageOperationStatus.GENERAL_ERROR)); - + when(nodeFilterValidator.validateComponentFilter(service, Collections.singletonList(constraint), + NodeFilterConstraintAction.UPDATE)).thenReturn(Either.left(true)); when(graphLockOperation.unlockComponent(componentId, NodeTypeEnum.Service)) .thenReturn(StorageOperationStatus.OK); final List<String> constraints = requirementSubstitutionFilterPropertyDataDefinition.getConstraints(); assertThrows(BusinessLogicException.class, () -> componentSubstitutionFilterBusinessLogic - .updateSubstitutionFilter(componentId, componentInstanceId, constraints, true, ComponentTypeEnum.SERVICE)); + .updateSubstitutionFilter(componentId, constraints, true, ComponentTypeEnum.SERVICE)); verify(toscaOperationFacade, times(1)).getToscaElement(componentId); - verify(nodeFilterValidator, times(1)).validateFilter(service, componentInstanceId, - Collections.singletonList(constraint), NodeFilterConstraintAction.UPDATE); - } - - @Test - public void updateSubstitutionFilterFailWithFilterNotFoundTest() { - when(toscaOperationFacade.getToscaElement(componentId)).thenReturn(Either.left(service)); - when(nodeFilterValidator.validateFilter(service, componentInstanceId, - Collections.singletonList(constraint), NodeFilterConstraintAction.UPDATE)).thenReturn(Either.left(true)); - - assertThrows(BusinessLogicException.class, () -> componentSubstitutionFilterBusinessLogic - .updateSubstitutionFilter(componentId, componentInstanceId, - requirementSubstitutionFilterPropertyDataDefinition.getConstraints(), true, - ComponentTypeEnum.SERVICE)); - - verify(toscaOperationFacade, times(1)).getToscaElement(componentId); - verify(nodeFilterValidator, times(1)).validateFilter(service, componentInstanceId, - Collections.singletonList(constraint), NodeFilterConstraintAction.UPDATE); - } - - @Test - public void updateSubstitutionFilterFailValidationTest() { - when(toscaOperationFacade.getToscaElement(componentId)).thenReturn(Either.left(service)); - - final UIConstraint uiConstraint = - new UIConstraint("invalidProperty", constraintOperator, sourceType, sourceName, propertyValue); - constraint = new ConstraintConvertor().convert(uiConstraint); - requirementSubstitutionFilterPropertyDataDefinition.setConstraints(Collections.singletonList(constraint)); - - when(responseFormat.getFormattedMessage()).thenReturn(ActionStatus.SELECTED_PROPERTY_NOT_PRESENT.name()); - - when(nodeFilterValidator.validateFilter(service, componentInstanceId, - Collections.singletonList(constraint), NodeFilterConstraintAction.UPDATE)) - .thenReturn(Either.right(responseFormat)); - - assertThrows(BusinessLogicException.class, () -> componentSubstitutionFilterBusinessLogic - .updateSubstitutionFilter(componentId, componentInstanceId, - requirementSubstitutionFilterPropertyDataDefinition.getConstraints(), true, - ComponentTypeEnum.SERVICE)); - - verify(toscaOperationFacade, times(1)).getToscaElement(componentId); - verify(nodeFilterValidator, times(1)).validateFilter(service, componentInstanceId, - Collections.singletonList(constraint), NodeFilterConstraintAction.UPDATE); + verify(graphLockOperation, times(1)).lockComponent(componentId, NodeTypeEnum.Service); + verify(nodeFilterValidator, times(1)).validateComponentFilter(service, + Collections.singletonList(constraint), NodeFilterConstraintAction.UPDATE); + verify(graphLockOperation, times(1)).unlockComponent(componentId, NodeTypeEnum.Service); } @Test public void deleteSubstitutionFilterTest() throws BusinessLogicException { substitutionFilterDataDefinition.setProperties(new ListDataDefinition<>()); - componentInstance.setSubstitutionFilter(substitutionFilterDataDefinition); + service.setSubstitutionFilter(substitutionFilterDataDefinition); when(toscaOperationFacade.getToscaElement(componentId)).thenReturn(Either.left(service)); - when(nodeFilterValidator.validateFilter(service, componentInstanceId, - Collections.singletonList(constraint), NodeFilterConstraintAction.DELETE)).thenReturn(Either.left(true)); - - when(nodeFilterValidator.validateComponentInstanceExist(service, componentInstanceId)) - .thenReturn(Either.left(true)); when(graphLockOperation.lockComponent(componentId, NodeTypeEnum.Service)) .thenReturn(StorageOperationStatus.OK); - when(substitutionFilterOperation.deleteConstraint(anyString(), anyString(), - any(SubstitutionFilterDataDefinition.class), anyInt())) + when(substitutionFilterOperation.deleteConstraint(anyString(), any(SubstitutionFilterDataDefinition.class), anyInt())) .thenReturn(Either.left(substitutionFilterDataDefinition)); when(graphLockOperation.unlockComponent(componentId, NodeTypeEnum.Service)) .thenReturn(StorageOperationStatus.OK); final Optional<SubstitutionFilterDataDefinition> result = componentSubstitutionFilterBusinessLogic - .deleteSubstitutionFilter(componentId, componentInstanceId, NodeFilterConstraintAction.DELETE, constraint, - 0, true, ComponentTypeEnum.SERVICE); + .deleteSubstitutionFilter(componentId, anyInt(), true, ComponentTypeEnum.SERVICE); - assertThat(result).isPresent(); - assertThat(result.get().getProperties().getListToscaDataDefinition()).hasSize(0); verify(toscaOperationFacade, times(1)).getToscaElement(componentId); - verify(nodeFilterValidator, times(1)).validateFilter(service, componentInstanceId, - Collections.singletonList(constraint), NodeFilterConstraintAction.DELETE); - verify(nodeFilterValidator, times(1)).validateComponentInstanceExist(service, componentInstanceId); verify(graphLockOperation, times(1)).lockComponent(componentId, NodeTypeEnum.Service); - verify(substitutionFilterOperation, times(1)).deleteConstraint(componentId, componentInstanceId, - substitutionFilterDataDefinition, 0); + verify(substitutionFilterOperation, times(1)).deleteConstraint(componentId, + substitutionFilterDataDefinition, 0); verify(graphLockOperation, times(1)).unlockComponent(componentId, NodeTypeEnum.Service); } @Test public void deleteSubstitutionFilterFailTest() { - componentInstance.setSubstitutionFilter(substitutionFilterDataDefinition); + service.setSubstitutionFilter(substitutionFilterDataDefinition); when(toscaOperationFacade.getToscaElement(componentId)).thenReturn(Either.left(service)); - when(nodeFilterValidator.validateFilter(service, componentInstanceId, - Collections.singletonList(constraint), NodeFilterConstraintAction.DELETE)).thenReturn(Either.left(true)); - - when(nodeFilterValidator.validateComponentInstanceExist(service, componentInstanceId)) - .thenReturn(Either.left(true)); when(graphLockOperation.lockComponent(componentId, NodeTypeEnum.Service)) .thenReturn(StorageOperationStatus.OK); - when(substitutionFilterOperation.deleteConstraint(anyString(), anyString(), + when(substitutionFilterOperation.deleteConstraint(anyString(), any(SubstitutionFilterDataDefinition.class), anyInt())) .thenReturn(Either.right(StorageOperationStatus.GENERAL_ERROR)); when(graphLockOperation.unlockComponent(componentId, NodeTypeEnum.Service)) .thenReturn(StorageOperationStatus.OK); + final List<String> constraints = requirementSubstitutionFilterPropertyDataDefinition.getConstraints(); assertThrows(BusinessLogicException.class, () -> componentSubstitutionFilterBusinessLogic - .deleteSubstitutionFilter(componentId, componentInstanceId, NodeFilterConstraintAction.DELETE, constraint, - 0, true, ComponentTypeEnum.SERVICE)); + .deleteSubstitutionFilter(componentId, anyInt(),true, ComponentTypeEnum.SERVICE)); verify(toscaOperationFacade, times(1)).getToscaElement(componentId); - verify(nodeFilterValidator, times(1)).validateFilter(service, componentInstanceId, - Collections.singletonList(constraint), NodeFilterConstraintAction.DELETE); - verify(nodeFilterValidator, times(1)).validateComponentInstanceExist(service, componentInstanceId); - verify(substitutionFilterOperation, times(1)).deleteConstraint(componentId, componentInstanceId, - substitutionFilterDataDefinition, 0); + verify(graphLockOperation, times(1)).lockComponent(componentId, NodeTypeEnum.Service); + verify(substitutionFilterOperation, times(1)).deleteConstraint(componentId, + substitutionFilterDataDefinition, 0); verify(graphLockOperation, times(1)).unlockComponent(componentId, NodeTypeEnum.Service); } - @Test - public void deleteSubstitutionFilterFailValidationTest() { - when(toscaOperationFacade.getToscaElement(componentId)).thenReturn(Either.left(service)); - when(nodeFilterValidator.validateFilter(service, componentInstanceId, - Collections.singletonList(constraint), NodeFilterConstraintAction.DELETE)).thenReturn(Either.left(true)); - - when(nodeFilterValidator.validateComponentInstanceExist(service, componentInstanceId)) - .thenReturn(Either.left(true)); - - assertThrows(BusinessLogicException.class, () -> componentSubstitutionFilterBusinessLogic - .deleteSubstitutionFilter(componentId, componentInstanceId, NodeFilterConstraintAction.DELETE, constraint, - 0, true, ComponentTypeEnum.SERVICE)); - - verify(toscaOperationFacade, times(1)).getToscaElement(componentId); - verify(nodeFilterValidator, times(1)).validateFilter(service, componentInstanceId, - Collections.singletonList(constraint), NodeFilterConstraintAction.DELETE); - } - public void initResource() { try { service = new Service(); service.setName("MyTestService"); service.setUniqueId(componentId); - componentInstance = new ComponentInstance(); - componentInstance.setUniqueId(componentInstanceId); - componentInstance.setName("myComponentInstance"); - componentInstance.setDirectives(ConfigurationManager.getConfigurationManager().getConfiguration() - .getDirectives()); - final UIConstraint uiConstraint = new UIConstraint(servicePropertyName, constraintOperator, sourceType, sourceName, propertyValue); constraint = new ConstraintConvertor().convert(uiConstraint); @@ -459,22 +355,9 @@ public class ComponentSubstitutionFilterBusinessLogicTest extends BaseBusinessLo substitutionFilterDataDefinition.setProperties(listDataDefinition); substitutionFilterDataDefinition.setID("SUBSTITUTION_FILTER_UID"); - service.setComponentInstances(singletonList(componentInstance)); - final PropertyDefinition property = new PropertyDefinition(); property.setName(uiConstraint.getServicePropertyName()); - final List<ComponentInstanceProperty> origProperties = new ArrayList<>(); - final ComponentInstanceProperty origProperty = new ComponentInstanceProperty(); - origProperty.setName(uiConstraint.getServicePropertyName()); - origProperty.setValue(propertyValue); - origProperty.setType(uiConstraint.getSourceType()); - origProperties.add(origProperty); - - final Map<String, List<ComponentInstanceProperty>> componentInstanceProps = new HashMap<>(); - componentInstanceProps.put(componentInstanceId, origProperties); - - service.setComponentInstancesProperties(componentInstanceProps); service.setProperties(new LinkedList<>(Arrays.asList(property))); } catch (final Exception e) { fail(e.getMessage()); 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 b6b1dc5cd9..39259a899f 100644 --- a/catalog-be/src/test/java/org/openecomp/sdc/be/servlets/ComponentSubstitutionFilterServletTest.java +++ b/catalog-be/src/test/java/org/openecomp/sdc/be/servlets/ComponentSubstitutionFilterServletTest.java @@ -22,9 +22,11 @@ package org.openecomp.sdc.be.servlets; import static org.assertj.core.api.Assertions.assertThat; import static org.junit.jupiter.api.Assertions.assertNotNull; import static org.mockito.ArgumentMatchers.any; -import static org.mockito.ArgumentMatchers.anyBoolean; +import static org.mockito.ArgumentMatchers.anyInt; import static org.mockito.ArgumentMatchers.anyString; +import static org.mockito.ArgumentMatchers.anyBoolean; import static org.mockito.ArgumentMatchers.nullable; +import static org.mockito.ArgumentMatchers.anyList; import static org.mockito.Mockito.mock; import static org.mockito.Mockito.reset; import static org.mockito.Mockito.times; @@ -44,6 +46,7 @@ import javax.servlet.http.HttpSession; import javax.ws.rs.client.Entity; import javax.ws.rs.core.MediaType; import javax.ws.rs.core.Response; + import org.eclipse.jetty.http.HttpStatus; import org.glassfish.hk2.utilities.binding.AbstractBinder; import org.glassfish.jersey.server.ResourceConfig; @@ -58,7 +61,6 @@ import org.openecomp.sdc.be.components.impl.ComponentInstanceBusinessLogic; import org.openecomp.sdc.be.components.impl.ComponentSubstitutionFilterBusinessLogic; import org.openecomp.sdc.be.components.impl.ResourceImportManager; import org.openecomp.sdc.be.components.impl.exceptions.BusinessLogicException; -import org.openecomp.sdc.be.components.impl.utils.NodeFilterConstraintAction; import org.openecomp.sdc.be.components.validation.UserValidations; import org.openecomp.sdc.be.config.SpringConfig; import org.openecomp.sdc.be.dao.api.ActionStatus; @@ -89,7 +91,7 @@ public class ComponentSubstitutionFilterServletTest extends JerseyTest { private static final String sourceName = sourceType; private static final String propertyValue = "constraintValue"; private static final String componentId = "dac65869-dfb4-40d2-aa20-084324659ec1"; - private static final String componentInstance = "dac65869-dfb4-40d2-aa20-084324659ec1.service0"; + private static final String constraintType = "properties"; private static final String componentType = "services"; private static HttpServletRequest request; @@ -141,9 +143,9 @@ public class ComponentSubstitutionFilterServletTest extends JerseyTest { } @Test - public void addSubstitutionFilterTest() throws BusinessLogicException { - final String pathFormat = "/v1/catalog/%s/%s/resourceInstances/%s/substitutionFilter"; - final String path = String.format(pathFormat, componentType, componentId, componentInstance); + public void addSubstitutionFilterTest() throws Exception { + final String pathFormat = "/v1/catalog/%s/%s/substitutionFilter/%s"; + final String path = String.format(pathFormat, componentType, componentId, constraintType); when(userValidations.validateUserExists(user)).thenReturn(user); when(componentSubstitutionFilterBusinessLogic.validateUser(USER_ID)).thenReturn(user); @@ -164,15 +166,8 @@ public class ComponentSubstitutionFilterServletTest extends JerseyTest { assertNotNull(substitutionFilterDataDefinition); assertThat(substitutionFilterDataDefinition.getProperties().getListToscaDataDefinition()).hasSize(1); assertThat("controller_actor: {equal: constraintValue}\n").isEqualToIgnoringCase(constraint); - - when(componentSubstitutionFilterBusinessLogic.createSubstitutionFilterIfNotExist(componentId, - componentInstance, true, ComponentTypeEnum.SERVICE)) - .thenReturn(Optional.ofNullable(substitutionFilterDataDefinition)); - - when(componentSubstitutionFilterBusinessLogic - .addSubstitutionFilter(componentId, componentInstance, NodeFilterConstraintAction.ADD, - uiConstraint.getServicePropertyName(), constraint, true, ComponentTypeEnum.SERVICE)) - .thenReturn(Optional.ofNullable(substitutionFilterDataDefinition)); + when(componentSubstitutionFilterBusinessLogic.addSubstitutionFilter(componentId, uiConstraint.getServicePropertyName(), constraint, + true, ComponentTypeEnum.SERVICE)).thenReturn(Optional.of(substitutionFilterDataDefinition)); final Response response = target() .path(path) @@ -183,17 +178,14 @@ public class ComponentSubstitutionFilterServletTest extends JerseyTest { assertThat(response.getStatus()).isEqualTo(HttpStatus.OK_200); verify(componentSubstitutionFilterBusinessLogic, times(1)) - .createSubstitutionFilterIfNotExist(componentId, componentInstance, true, ComponentTypeEnum.SERVICE); - - verify(componentSubstitutionFilterBusinessLogic, times(1)) - .addSubstitutionFilter(anyString(), anyString(), any(NodeFilterConstraintAction.class), anyString(), - anyString(), anyBoolean(), any(ComponentTypeEnum.class)); + .addSubstitutionFilter(componentId, uiConstraint.getServicePropertyName(), constraint, + true, ComponentTypeEnum.SERVICE); } @Test public void addSubstitutionFilterFailConstraintParseTest() { - final String pathFormat = "/v1/catalog/%s/%s/resourceInstances/%s/substitutionFilter"; - final String path = String.format(pathFormat, componentType, componentId, componentInstance); + final String pathFormat = "/v1/catalog/%s/%s/substitutionFilter/%s"; + final String path = String.format(pathFormat, componentType, componentId, constraintType); when(userValidations.validateUserExists(user)).thenReturn(user); when(componentSubstitutionFilterBusinessLogic.validateUser(USER_ID)).thenReturn(user); @@ -212,9 +204,9 @@ public class ComponentSubstitutionFilterServletTest extends JerseyTest { } @Test - public void addSubstitutionFilterFailTest() throws BusinessLogicException { - final String pathFormat = "/v1/catalog/%s/%s/resourceInstances/%s/substitutionFilter"; - final String path = String.format(pathFormat, componentType, componentId, componentInstance); + public void addSubstitutionFilterFailTest() { + final String pathFormat = "/v1/catalog/%s/%s/substitutionFilter/%s"; + final String path = String.format(pathFormat, componentType, componentId, constraintType); when(userValidations.validateUserExists(user)).thenReturn(user); when(componentSubstitutionFilterBusinessLogic.validateUser(USER_ID)).thenReturn(user); @@ -223,10 +215,6 @@ public class ComponentSubstitutionFilterServletTest extends JerseyTest { when(componentsUtils.parseToConstraint(anyString(), any(User.class), any(ComponentTypeEnum.class))) .thenReturn(Optional.of(uiConstraint)); - when(componentSubstitutionFilterBusinessLogic.createSubstitutionFilterIfNotExist(componentId, - componentInstance, true, ComponentTypeEnum.SERVICE)) - .thenReturn(Optional.empty()); - final Response response = target() .path(path) .request(MediaType.APPLICATION_JSON) @@ -234,15 +222,12 @@ public class ComponentSubstitutionFilterServletTest extends JerseyTest { .post(Entity.entity(inputJson, MediaType.APPLICATION_JSON)); assertThat(response.getStatus()).isEqualTo(HttpStatus.INTERNAL_SERVER_ERROR_500); - - verify(componentSubstitutionFilterBusinessLogic, times(1)) - .createSubstitutionFilterIfNotExist(componentId, componentInstance, true, ComponentTypeEnum.SERVICE); } @Test public void updateSubstitutionFilterTest() throws BusinessLogicException { - final String pathFormat = "/v1/catalog/%s/%s/resourceInstances/%s/substitutionFilter"; - final String path = String.format(pathFormat, componentType, componentId, componentInstance); + final String pathFormat = "/v1/catalog/%s/%s/substitutionFilter/%s"; + final String path = String.format(pathFormat, componentType, componentId, constraintType); when(userValidations.validateUserExists(user)).thenReturn(user); when(componentSubstitutionFilterBusinessLogic.validateUser(USER_ID)).thenReturn(user); @@ -253,7 +238,7 @@ public class ComponentSubstitutionFilterServletTest extends JerseyTest { any(User.class))).thenReturn(Collections.singletonList(uiConstraint)); when(componentSubstitutionFilterBusinessLogic.updateSubstitutionFilter(componentId.toLowerCase(), - componentInstance, Collections.singletonList(constraint), true, ComponentTypeEnum.SERVICE)) + Collections.singletonList(constraint), true, ComponentTypeEnum.SERVICE)) .thenReturn(Optional.ofNullable(substitutionFilterDataDefinition)); final Response response = target() @@ -265,14 +250,13 @@ public class ComponentSubstitutionFilterServletTest extends JerseyTest { assertThat(response.getStatus()).isEqualTo(HttpStatus.OK_200); verify(componentSubstitutionFilterBusinessLogic, times(1)) - .updateSubstitutionFilter(componentId.toLowerCase(), componentInstance, - Collections.singletonList(constraint), true, ComponentTypeEnum.SERVICE); + .updateSubstitutionFilter(anyString(), anyList(), anyBoolean(), any(ComponentTypeEnum.class)); } @Test public void updateSubstitutionFilterFailConstraintParseTest() { - final String pathFormat = "/v1/catalog/%s/%s/resourceInstances/%s/substitutionFilter"; - final String path = String.format(pathFormat, componentType, componentId, componentInstance); + final String pathFormat = "/v1/catalog/%s/%s/substitutionFilter/%s"; + final String path = String.format(pathFormat, componentType, componentId, constraintType); when(userValidations.validateUserExists(user)).thenReturn(user); when(componentSubstitutionFilterBusinessLogic.validateUser(USER_ID)).thenReturn(user); @@ -291,9 +275,9 @@ public class ComponentSubstitutionFilterServletTest extends JerseyTest { } @Test - public void updateSubstitutionFilterFailTest() throws BusinessLogicException { - final String pathFormat = "/v1/catalog/%s/%s/resourceInstances/%s/substitutionFilter"; - final String path = String.format(pathFormat, componentType, componentId, componentInstance); + public void updateSubstitutionFilterFailTest() { + final String pathFormat = "/v1/catalog/%s/%s/substitutionFilter/%s"; + final String path = String.format(pathFormat, componentType, componentId, constraintType); when(userValidations.validateUserExists(user)).thenReturn(user); when(componentSubstitutionFilterBusinessLogic.validateUser(USER_ID)).thenReturn(user); @@ -302,10 +286,6 @@ public class ComponentSubstitutionFilterServletTest extends JerseyTest { when(componentsUtils.validateAndParseConstraint(ArgumentMatchers.any(ComponentTypeEnum.class), anyString(), any(User.class))).thenReturn(Collections.singletonList(uiConstraint)); - when(componentSubstitutionFilterBusinessLogic.updateSubstitutionFilter(componentId.toLowerCase(), - componentInstance, Collections.singletonList(constraint), true, ComponentTypeEnum.SERVICE)) - .thenReturn(Optional.empty()); - final Response response = target() .path(path) .request(MediaType.APPLICATION_JSON) @@ -313,24 +293,20 @@ public class ComponentSubstitutionFilterServletTest extends JerseyTest { .put(Entity.entity(inputJson, MediaType.APPLICATION_JSON)); assertThat(response.getStatus()).isEqualTo(HttpStatus.INTERNAL_SERVER_ERROR_500); - - verify(componentSubstitutionFilterBusinessLogic, times(1)) - .updateSubstitutionFilter(componentId.toLowerCase(), componentInstance, - Collections.singletonList(constraint), true, ComponentTypeEnum.SERVICE); } @Test public void deleteSubstitutionFilterConstraintTest() throws BusinessLogicException { - final String pathFormat = "/v1/catalog/%s/%s/resourceInstances/%s/substitutionFilter/0"; - final String path = String.format(pathFormat, componentType, componentId, componentInstance); + final String pathFormat = "/v1/catalog/%s/%s/substitutionFilter/%s/0"; + final String path = String.format(pathFormat, componentType, componentId, constraintType); when(userValidations.validateUserExists(user)).thenReturn(user); when(componentSubstitutionFilterBusinessLogic.validateUser(USER_ID)).thenReturn(user); when(responseFormat.getStatus()).thenReturn(HttpStatus.OK_200); when(componentsUtils.getResponseFormat(ActionStatus.OK)).thenReturn(responseFormat); - when(componentSubstitutionFilterBusinessLogic.deleteSubstitutionFilter(componentId, componentInstance, - NodeFilterConstraintAction.DELETE, null, 0, true, ComponentTypeEnum.SERVICE)) + when(componentSubstitutionFilterBusinessLogic.deleteSubstitutionFilter(componentId, 0, + true, ComponentTypeEnum.SERVICE)) .thenReturn(Optional.ofNullable(substitutionFilterDataDefinition)); final Response response = target() @@ -342,23 +318,18 @@ public class ComponentSubstitutionFilterServletTest extends JerseyTest { assertThat(response.getStatus()).isEqualTo(HttpStatus.OK_200); verify(componentSubstitutionFilterBusinessLogic, times(1)) - .deleteSubstitutionFilter(componentId, componentInstance, - NodeFilterConstraintAction.DELETE, null, 0, true, ComponentTypeEnum.SERVICE); + .deleteSubstitutionFilter(anyString(), anyInt(), anyBoolean(), any(ComponentTypeEnum.class)); } @Test - public void deleteSubstitutionFilterConstraintFailTest() throws BusinessLogicException { - final String pathFormat = "/v1/catalog/%s/%s/resourceInstances/%s/substitutionFilter/0"; - final String path = String.format(pathFormat, componentType, componentId, componentInstance); + public void deleteSubstitutionFilterConstraintFailTest() { + final String pathFormat = "/v1/catalog/%s/%s/substitutionFilter/%s/0"; + final String path = String.format(pathFormat, componentType, componentId, constraintType); when(userValidations.validateUserExists(user)).thenReturn(user); when(componentSubstitutionFilterBusinessLogic.validateUser(USER_ID)).thenReturn(user); when(componentsUtils.getResponseFormat(ActionStatus.OK)).thenReturn(responseFormat); - when(componentSubstitutionFilterBusinessLogic.deleteSubstitutionFilter(componentId, componentInstance, - NodeFilterConstraintAction.DELETE, null, 0, true, ComponentTypeEnum.SERVICE)) - .thenReturn(Optional.empty()); - final Response response = target() .path(path) .request(MediaType.APPLICATION_JSON) @@ -366,11 +337,6 @@ public class ComponentSubstitutionFilterServletTest extends JerseyTest { .delete(Response.class); assertThat(response.getStatus()).isEqualTo(HttpStatus.INTERNAL_SERVER_ERROR_500); - - verify(componentSubstitutionFilterBusinessLogic, times(1)) - .deleteSubstitutionFilter(componentId, componentInstance, - NodeFilterConstraintAction.DELETE, null, 0, true, ComponentTypeEnum.SERVICE); - } private static void createMocks() { diff --git a/catalog-model/src/main/java/org/openecomp/sdc/be/model/Component.java b/catalog-model/src/main/java/org/openecomp/sdc/be/model/Component.java index ba73e77e05..8f58a3c4d2 100644 --- a/catalog-model/src/main/java/org/openecomp/sdc/be/model/Component.java +++ b/catalog-model/src/main/java/org/openecomp/sdc/be/model/Component.java @@ -87,6 +87,7 @@ public abstract class Component implements PropertiesOwner { private Map<String, SubstitutionFilterDataDefinition> substitutionFilterComponents; private Map<String, InterfaceDefinition> interfaces; private List<DataTypeDefinition> dataTypes; + private SubstitutionFilterDataDefinition substitutionFilter; public Component(ComponentMetadataDefinition componentMetadataDefinition) { this.componentMetadataDefinition = componentMetadataDefinition; diff --git a/catalog-model/src/main/java/org/openecomp/sdc/be/model/ComponentInstance.java b/catalog-model/src/main/java/org/openecomp/sdc/be/model/ComponentInstance.java index 5b99f99bd2..fd4feeb035 100644 --- a/catalog-model/src/main/java/org/openecomp/sdc/be/model/ComponentInstance.java +++ b/catalog-model/src/main/java/org/openecomp/sdc/be/model/ComponentInstance.java @@ -47,7 +47,6 @@ public class ComponentInstance extends ComponentInstanceDataDefinition implement private Map<String, Object> interfaces; private List<PropertyDefinition> properties; private CINodeFilterDataDefinition nodeFilter; - private SubstitutionFilterDataDefinition substitutionFilter; private List<InputDefinition> inputs; public ComponentInstance() { diff --git a/catalog-model/src/main/java/org/openecomp/sdc/be/model/ComponentParametersView.java b/catalog-model/src/main/java/org/openecomp/sdc/be/model/ComponentParametersView.java index f1785c76f8..505b8e6c7c 100644 --- a/catalog-model/src/main/java/org/openecomp/sdc/be/model/ComponentParametersView.java +++ b/catalog-model/src/main/java/org/openecomp/sdc/be/model/ComponentParametersView.java @@ -50,7 +50,6 @@ public class ComponentParametersView { private boolean ignoreServicePath = true; private boolean ignorePolicies = false; private boolean ignoreNodeFilterRequirements = false; - private boolean ignoreSubstitutionFilterRequirements = false; private boolean ignoreNodeFilter = false; private boolean ignoreSubstitutionFilter = false; private boolean ignoreDataType = false; @@ -157,7 +156,6 @@ public class ComponentParametersView { this.setIgnoreNodeFilter(false); break; case SUBSTITUTION_FILTER: - this.setIgnoreSubstitutionFilterRequirements(false); this.setIgnoreSubstitutionFilter(false); break; case COMPONENT_INSTANCES_INTERFACES: @@ -223,9 +221,6 @@ public class ComponentParametersView { if (ignoreNodeFilterRequirements){ component.setNodeFilterComponents(null); } - if (ignoreSubstitutionFilterRequirements){ - component.setSubstitutionFilterComponents(null); - } if (ignoreInterfaces && ignoreInterfaceInstances && componentType == ComponentTypeEnum.RESOURCE) { component.setInterfaces(null); @@ -268,14 +263,6 @@ public class ComponentParametersView { this.ignoreNodeFilterRequirements = ignoreNodeFilter; } - public boolean isIgnoreSubstitutionFilterRequirements() { - return ignoreSubstitutionFilterRequirements; - } - - public void setIgnoreSubstitutionFilterRequirements(boolean ignoreSubstitutionFilterRequirements) { - this.ignoreSubstitutionFilterRequirements = ignoreSubstitutionFilterRequirements; - } - public void disableAll() { ignoreUsers = true; ignoreGroups = true; @@ -299,7 +286,6 @@ public class ComponentParametersView { ignoreCapabiltyProperties = true; ignoreServicePath = true; ignoreNodeFilterRequirements = true; - ignoreSubstitutionFilterRequirements = true; ignoreNodeFilter = true; ignoreSubstitutionFilter = true; ignoreDataType = true; diff --git a/catalog-model/src/main/java/org/openecomp/sdc/be/model/jsonjanusgraph/operations/SubstitutionFilterOperation.java b/catalog-model/src/main/java/org/openecomp/sdc/be/model/jsonjanusgraph/operations/SubstitutionFilterOperation.java index 9007e20998..0062e2eaa7 100644 --- a/catalog-model/src/main/java/org/openecomp/sdc/be/model/jsonjanusgraph/operations/SubstitutionFilterOperation.java +++ b/catalog-model/src/main/java/org/openecomp/sdc/be/model/jsonjanusgraph/operations/SubstitutionFilterOperation.java @@ -22,6 +22,7 @@ package org.openecomp.sdc.be.model.jsonjanusgraph.operations; import com.google.common.collect.ImmutableList; import fj.data.Either; import java.util.List; +import java.util.Objects; import org.openecomp.sdc.be.dao.janusgraph.JanusGraphOperationStatus; import org.openecomp.sdc.be.dao.jsongraph.GraphVertex; import org.openecomp.sdc.be.dao.jsongraph.types.EdgeLabelEnum; @@ -44,78 +45,70 @@ public class SubstitutionFilterOperation extends BaseOperation { private static final Logger LOGGER = Logger.getLogger(SubstitutionFilterOperation.class); public Either<SubstitutionFilterDataDefinition, StorageOperationStatus> createSubstitutionFilter( - final String componentId, final String componentInstanceId) { + final String componentId) { - return addOrUpdateSubstitutionFilter(false, componentId, componentInstanceId, - new SubstitutionFilterDataDefinition()); + return addOrUpdateSubstitutionFilter(false, componentId, new SubstitutionFilterDataDefinition()); } public Either<SubstitutionFilterDataDefinition, StorageOperationStatus> deleteConstraint( - final String serviceId, final String componentInstanceId, - final SubstitutionFilterDataDefinition substitutionFilterDataDefinition, final int propertyIndex) { + final String serviceId, final SubstitutionFilterDataDefinition substitutionFilterDataDefinition, + final int propertyIndex) { final ListDataDefinition<RequirementSubstitutionFilterPropertyDataDefinition> properties = - substitutionFilterDataDefinition.getProperties(); + substitutionFilterDataDefinition.getProperties(); properties.getListToscaDataDefinition().remove(propertyIndex); substitutionFilterDataDefinition.setProperties(properties); - return addOrUpdateSubstitutionFilter(true, serviceId, componentInstanceId, substitutionFilterDataDefinition); + + return addOrUpdateSubstitutionFilter(true, serviceId, substitutionFilterDataDefinition); } - public Either<SubstitutionFilterDataDefinition, StorageOperationStatus> addNewProperty( - final String componentId, final String componentInstanceId, - final SubstitutionFilterDataDefinition substitutionFilterDataDefinition, - final RequirementSubstitutionFilterPropertyDataDefinition requirementSubstitutionFilterPropertyDataDefinition) { + public Either<SubstitutionFilterDataDefinition, StorageOperationStatus> addPropertyFilter( + final String componentId, final SubstitutionFilterDataDefinition substitutionFilterDataDefinition, + final RequirementSubstitutionFilterPropertyDataDefinition substitutionFilterPropertyDataDefinition) { - ListDataDefinition<RequirementSubstitutionFilterPropertyDataDefinition> properties = - substitutionFilterDataDefinition.getProperties(); - if (properties == null) { - properties = new ListDataDefinition<>(); - substitutionFilterDataDefinition.setProperties(properties); - } - properties.getListToscaDataDefinition().add(requirementSubstitutionFilterPropertyDataDefinition); - substitutionFilterDataDefinition.setProperties(properties); - return addOrUpdateSubstitutionFilter(true, componentId, componentInstanceId, substitutionFilterDataDefinition); + final SubstitutionFilterDataDefinition substitutionFilterDataDefinition1 = + Objects.requireNonNullElseGet(substitutionFilterDataDefinition, SubstitutionFilterDataDefinition::new); + final ListDataDefinition<RequirementSubstitutionFilterPropertyDataDefinition> properties = + Objects.requireNonNullElseGet(substitutionFilterDataDefinition1.getProperties(), ListDataDefinition::new); + properties.getListToscaDataDefinition().add(substitutionFilterPropertyDataDefinition); + substitutionFilterDataDefinition1.setProperties(properties); + return addOrUpdateSubstitutionFilter(true, componentId, substitutionFilterDataDefinition1); } - public Either<SubstitutionFilterDataDefinition, StorageOperationStatus> updateSubstitutionFilter( - final String serviceId, final String componentInstanceId, - final SubstitutionFilterDataDefinition substitutionFilterDataDefinition, - final List<RequirementSubstitutionFilterPropertyDataDefinition> requirementSubstitutionFilterPropertyDataDefinitions) { + public Either<SubstitutionFilterDataDefinition, StorageOperationStatus> updateProperties( + final String componentId, final SubstitutionFilterDataDefinition substitutionFilterDataDefinition, + final List<RequirementSubstitutionFilterPropertyDataDefinition> requirementSubstitutionFilterPropertyDataDefinition) { final ListDataDefinition<RequirementSubstitutionFilterPropertyDataDefinition> properties = substitutionFilterDataDefinition.getProperties(); properties.getListToscaDataDefinition().clear(); - properties.getListToscaDataDefinition().addAll(requirementSubstitutionFilterPropertyDataDefinitions); + properties.getListToscaDataDefinition().addAll(requirementSubstitutionFilterPropertyDataDefinition); substitutionFilterDataDefinition.setProperties(properties); - return addOrUpdateSubstitutionFilter(true, serviceId, componentInstanceId, - substitutionFilterDataDefinition); + return addOrUpdateSubstitutionFilter(true, componentId, substitutionFilterDataDefinition); } private Either<SubstitutionFilterDataDefinition, StorageOperationStatus> addOrUpdateSubstitutionFilter( - final boolean isUpdateAction, final String componentId, final String componentInstanceId, + final boolean isUpdateAction, final String componentId, final SubstitutionFilterDataDefinition substitutionFilterDataDefinition) { - StorageOperationStatus statusRes; - Either<GraphVertex, JanusGraphOperationStatus> getToscaElementRes; - - getToscaElementRes = janusGraphDao.getVertexById(componentId, JsonParseFlagEnum.NoParse); - if (getToscaElementRes.isRight()) { - final JanusGraphOperationStatus status = getToscaElementRes.right().value(); + final Either<GraphVertex, JanusGraphOperationStatus> toscaElementEither = + janusGraphDao.getVertexById(componentId, JsonParseFlagEnum.NoParse); + if (toscaElementEither.isRight()) { + final JanusGraphOperationStatus status = toscaElementEither.right().value(); CommonUtility.addRecordToLog(LOGGER, CommonUtility.LogLevelEnum.DEBUG, "Failed to get tosca element {} upon adding the properties. Status is {}. ", componentId, status); - statusRes = DaoStatusConverter.convertJanusGraphStatusToStorageStatus(status); - return Either.right(statusRes); + return Either.right(DaoStatusConverter.convertJanusGraphStatusToStorageStatus(status)); } - final GraphVertex serviceVertex = getToscaElementRes.left().value(); - substitutionFilterDataDefinition.setID(componentInstanceId); - statusRes = performUpdateToscaAction(isUpdateAction, serviceVertex, + final GraphVertex serviceVertex = toscaElementEither.left().value(); + substitutionFilterDataDefinition.setID(componentId); + final StorageOperationStatus operationStatus = performUpdateToscaAction(isUpdateAction, serviceVertex, ImmutableList.of(substitutionFilterDataDefinition)); - if (!statusRes.equals(StorageOperationStatus.OK)) { + if (!StorageOperationStatus.OK.equals(operationStatus)) { janusGraphDao.rollback(); LOGGER.error(EcompErrorSeverity.ERROR, EcompLoggerErrorCode.BUSINESS_PROCESS_ERROR, " Failed to perform tosca update for substitution filter in service {} , component instance {}. status is {}", - componentId, componentInstanceId, statusRes); - return Either.right(statusRes); + componentId, "componentInstanceId", operationStatus); + return Either.right(operationStatus); } janusGraphDao.commit(); return Either.left(substitutionFilterDataDefinition); diff --git a/catalog-model/src/main/java/org/openecomp/sdc/be/model/jsonjanusgraph/utils/ModelConverter.java b/catalog-model/src/main/java/org/openecomp/sdc/be/model/jsonjanusgraph/utils/ModelConverter.java index 839ae27a19..4d2480f6af 100644 --- a/catalog-model/src/main/java/org/openecomp/sdc/be/model/jsonjanusgraph/utils/ModelConverter.java +++ b/catalog-model/src/main/java/org/openecomp/sdc/be/model/jsonjanusgraph/utils/ModelConverter.java @@ -909,14 +909,9 @@ public class ModelConverter { final Component component) { final Map<String, SubstitutionFilterDataDefinition> filters = topologyTemplate .getSubstitutionFilterDataDefinitionMap(); - final Map<String, SubstitutionFilterDataDefinition> copy; if (MapUtils.isNotEmpty(filters)) { - copy = filters.entrySet().stream() - .collect(Collectors.toMap(Map.Entry::getKey, e -> new SubstitutionFilterDataDefinition(e.getValue()))); - } else { - copy = new HashMap<>(); + component.setSubstitutionFilter(filters.get(component.getUniqueId())); } - component.setSubstitutionFilterComponents(copy); } private static void convertServiceApiArtifacts(TopologyTemplate topologyTemplate, Service service) { @@ -1361,8 +1356,6 @@ public class ModelConverter { List<ComponentInstance> componentInstances = new ArrayList<>(); ComponentInstance currComponentInstance; Map<String, CINodeFilterDataDefinition> nodeFilterComponents = topologyTemplate.getNodeFilterComponents(); - Map<String, SubstitutionFilterDataDefinition> substitutionFilterDataDefinitionMap = topologyTemplate - .getSubstitutionFilterDataDefinitionMap(); for (Map.Entry<String, ComponentInstanceDataDefinition> entry : topologyTemplate.getComponentInstances().entrySet()) { String key = entry.getKey(); @@ -1375,9 +1368,6 @@ public class ModelConverter { if(MapUtils.isNotEmpty(nodeFilterComponents) && nodeFilterComponents.containsKey(key)){ currComponentInstance.setNodeFilter(nodeFilterComponents.get(key)); } - if(MapUtils.isNotEmpty(substitutionFilterDataDefinitionMap) && substitutionFilterDataDefinitionMap.containsKey(key)) { - currComponentInstance.setSubstitutionFilter(substitutionFilterDataDefinitionMap.get(key)); - } if(topologyTemplate.getInstProperties() != null && topologyTemplate.getInstProperties().containsKey(key) && topologyTemplate.getInstProperties().get(key) != null ){ List<PropertyDefinition> instanceProps = topologyTemplate.getInstProperties().get(key).getMapToscaDataDefinition().entrySet().stream().map(e -> new PropertyDefinition(e.getValue())).collect(Collectors.toList()); currComponentInstance.setProperties(instanceProps); 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 new file mode 100644 index 0000000000..0a0cbeb4bf --- /dev/null +++ b/catalog-ui/src/app/models/tosca-filter-constraint-type.enum.ts @@ -0,0 +1,22 @@ +/* + * ============LICENSE_START======================================================= + * Copyright (C) 2020 Nordix Foundation + * ================================================================================ + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + * SPDX-License-Identifier: Apache-2.0 + * ============LICENSE_END========================================================= + */ + +export enum ToscaFilterConstraintType { + PROPERTIES = 'properties' +} diff --git a/catalog-ui/src/app/ng2/components/logic/substitution-filter/substitution-filter.component.html b/catalog-ui/src/app/ng2/components/logic/substitution-filter/substitution-filter.component.html index f781e6c89b..01329b70d1 100644 --- a/catalog-ui/src/app/ng2/components/logic/substitution-filter/substitution-filter.component.html +++ b/catalog-ui/src/app/ng2/components/logic/substitution-filter/substitution-filter.component.html @@ -19,32 +19,39 @@ --> <div class="substitution-filter"> + <loader [display]="isLoading" [size]="'medium'" [relative]="true"></loader> + <div class="w-sdc-designer-sidebar-section"> + <sdc-accordion [title]="'Substitution Filter Properties'" [arrow-direction]="'right'" [open]="true"> + <div class="i-sdc-designer-sidebar-section-content-substitution-filter-section"> - <div *ngIf="compositeService.isService()" - class="i-sdc-designer-sidebar-section-content-item-rules-section"> + <div class="i-sdc-designer-sidebar-section-content-substitution-filter" + [ngClass]="{'hand': !readonly}" + *ngFor="let property of constraintProperties; let i = index"> + <div class="rule-details" [ngClass]="{'readonly': readonly}"> + <div class="rule-desc" (click)="!readonly && onSelectSubstitutionFilter(PROPERTIES, i)" + tooltips + tooltip="{{property.servicePropertyName + ' ' + getSymbol(property.constraintOperator) + ' ' + + (property.sourceName ? property.sourceName + ':' : '') + property.value}}"> + {{property.servicePropertyName + ' ' + getSymbol(property.constraintOperator) + + ' ' + + (property.sourceName ? property.sourceName + ':' : '') + property.value}} + </div> + <span *ngIf="!readonly" class="sprite-new delete-btn delete-icon" + (click)="openDeleteModal(PROPERTIES, i)" + data-tests-id="delete-input-button"></span> + </div> + </div> - <div class="i-sdc-designer-sidebar-section-content-item-rule" [ngClass]="{'hand': !readonly}" - *ngFor="let constraint of constraintObjects; let i = index"> - <div class="rule-details" [ngClass]="{'readonly': readonly}"> - <div class="rule-desc" (click)="!readonly && onSelectFilter(i)" tooltips - tooltip="{{constraint.servicePropertyName + ' ' + getSymbol(constraint.constraintOperator) + ' ' - + (constraint.sourceName ? constraint.sourceName + ':' : '') + constraint.value}}"> - {{constraint.servicePropertyName + ' ' + getSymbol(constraint.constraintOperator) + ' ' - + (constraint.sourceName ? constraint.sourceName + ':' : '') + constraint.value}} + <div class="w-sdc-designer-sidebar-section-substitution-filter-footer"> + <button + class="w-sdc-designer-sidebar-section-substitution-filter-footer-action add-rule-btn tlv-btn blue" + data-tests-id="add-rule-button" + (click)="onAddSubstitutionFilter(PROPERTIES)" + [disabled]="readonly"> + {{'ADD_SUBSTITUTION_FILTER' | translate}} + </button> </div> - <span *ngIf="!readonly" class="sprite-new delete-btn delete-icon" - (click)="openDeleteModal(i)" data-tests-id="delete-input-button"></span> </div> - </div> - - <div *ngIf="!isSubstitutionFilterSet()" class="w-sdc-designer-sidebar-section-footer"> - <button - class="w-sdc-designer-sidebar-section-footer-action tlv-btn blue" - data-tests-id="add-rule-button" - (click)="onAddSubstitutionFilter()" - [disabled]="readonly"> - {{'ADD_SUBSTITUTION_FILTER' | translate}} - </button> - </div> + </sdc-accordion> </div> </div> diff --git a/catalog-ui/src/app/ng2/components/logic/substitution-filter/substitution-filter.component.less b/catalog-ui/src/app/ng2/components/logic/substitution-filter/substitution-filter.component.less index cc41c3a69a..f0464774b5 100644 --- a/catalog-ui/src/app/ng2/components/logic/substitution-filter/substitution-filter.component.less +++ b/catalog-ui/src/app/ng2/components/logic/substitution-filter/substitution-filter.component.less @@ -25,8 +25,8 @@ .substitution-filter { - .i-sdc-designer-sidebar-section-content-item-rules-section { - .i-sdc-designer-sidebar-section-content-item-rule { + .i-sdc-designer-sidebar-section-content-substitution-filter-section { + .i-sdc-designer-sidebar-section-content-substitution-filter { border-bottom: 1px solid @main_color_o; padding: 5px 10px 5px 18px; position: relative; @@ -65,13 +65,44 @@ } } - .w-sdc-designer-sidebar-section-footer { + .w-sdc-designer-sidebar-section-substitution-filter-footer { margin-top: 10px; + margin-bottom: 10px; text-align: center; width: 100%; } - .w-sdc-designer-sidebar-section-footer-action { + .w-sdc-designer-sidebar-section-substitution-filter-footer-action { width: 180px; margin-top: 10px; } } + +/deep/.sdc-accordion { + margin-bottom: 0; + display: grid; + + .sdc-accordion-header { + background-color: #e6f6fb; + border-left: solid #009fdb 4px; + box-shadow: 0 0px 3px -1px rgba(0, 0, 0, 0.3); + margin-bottom: 2px; + width: auto; + height: auto; + padding: 10px; + color: #666666; + font-family: OpenSans-Semibold, sans-serif; + font-size: 14px; + } + + .sdc-accordion-body.open { + padding-left: 0; + padding-top: 0; + .sdc-accordion-header { /*Second level - nested accordion */ + background-color: #f8f8f8; + padding: 4px 20px 4px 37px; + border-bottom: 1px solid #d2d2d2; + border-left:none; + height: 30px; + } + } +} diff --git a/catalog-ui/src/app/ng2/components/logic/substitution-filter/substitution-filter.component.ts b/catalog-ui/src/app/ng2/components/logic/substitution-filter/substitution-filter.component.ts index a0fa2bb20b..aade8d8b73 100644 --- a/catalog-ui/src/app/ng2/components/logic/substitution-filter/substitution-filter.component.ts +++ b/catalog-ui/src/app/ng2/components/logic/substitution-filter/substitution-filter.component.ts @@ -28,11 +28,11 @@ import { import {ModalComponent} from 'app/ng2/components/ui/modal/modal.component'; import {ServiceDependenciesEditorComponent} from 'app/ng2/pages/service-dependencies-editor/service-dependencies-editor.component'; import {ModalService} from 'app/ng2/services/modal.service'; -import {ComponentGenericResponse} from 'app/ng2/services/responses/component-generic-response'; import {TranslateService} from 'app/ng2/shared/translator/translate.service'; import {ComponentMetadata} from '../../../../models/component-metadata'; import {ServiceInstanceObject} from '../../../../models/service-instance-properties-and-interfaces'; import {TopologyTemplateService} from '../../../services/component-services/topology-template.service'; +import {ToscaFilterConstraintType} from "../../../../models/tosca-filter-constraint-type.enum"; export class ConstraintObject { servicePropertyName: string; @@ -114,7 +114,8 @@ export class SubstitutionFilterComponent { isLoading: boolean; parentServiceInputs: InputBEModel[] = []; operatorTypes: any[]; - constraintObjects: ConstraintObject[] = []; + constraintProperties: ConstraintObject[] = []; + PROPERTIES: string = ToscaFilterConstraintType.PROPERTIES; @Input() readonly: boolean; @Input() compositeService: ComponentMetadata; @@ -122,6 +123,7 @@ export class SubstitutionFilterComponent { @Input() selectedInstanceSiblings: ServiceInstanceObject[]; @Input() selectedInstanceConstraints: ConstraintObject[] = []; @Input() selectedInstanceProperties: PropertyBEModel[] = []; + @Output() updateSubstitutionFilterProperties: EventEmitter<ConstraintObject[]> = new EventEmitter<ConstraintObject[]>(); @Output() updateConstraintListEvent: EventEmitter<ConstraintObject[]> = new EventEmitter<ConstraintObject[]>(); @Output() loadConstraintListEvent: EventEmitter<any> = new EventEmitter(); @Output() hasSubstitutionFilter = new EventEmitter<boolean>(); @@ -136,34 +138,35 @@ export class SubstitutionFilterComponent { {label: '<', value: OPERATOR_TYPES.LESS_THAN}, {label: '=', value: OPERATOR_TYPES.EQUAL} ]; - this.topologyTemplateService.getComponentInputsWithProperties(this.compositeService.componentType, this.compositeService.uniqueId).subscribe((result: ComponentGenericResponse) => { - this.parentServiceInputs = result.inputs; - }); - this.loadAllInstances(); + this.loadSubstitutionFilter(); this.translateService.languageChangedObservable.subscribe((lang) => { I18nTexts.translateTexts(this.translateService); }); } ngOnChanges(changes) { - if (changes.currentServiceInstance) { - this.currentServiceInstance = changes.currentServiceInstance.currentValue; + if (changes.compositeService) { + this.compositeService = changes.compositeService.currentValue; } if (changes.selectedInstanceConstraints && changes.selectedInstanceConstraints.currentValue !== changes.selectedInstanceConstraints.previousValue) { this.selectedInstanceConstraints = changes.selectedInstanceConstraints.currentValue; - this.loadAllInstances(); + this.loadSubstitutionFilter(); } } - public loadAllInstances = (): void => { - this.topologyTemplateService.getComponentCompositionData(this.compositeService.uniqueId, this.compositeService.componentType).subscribe((response) => { - response.componentInstances.forEach(componentInstance => this.getSubstitutionFilter(componentInstance)) - }) + private loadSubstitutionFilter = (): void => { + this.topologyTemplateService.getSubstitutionFilterConstraints(this.compositeService.componentType, this.compositeService.uniqueId) + .subscribe((response) => { + if (response.substitutionFilterForTopologyTemplate && response.substitutionFilterForTopologyTemplate[this.compositeService.uniqueId]) { + this.constraintProperties = response. + substitutionFilterForTopologyTemplate[this.compositeService.uniqueId].properties; + } + }); } - onAddSubstitutionFilter() { + onAddSubstitutionFilter = (constraintType: string) => { const cancelButton: ButtonModel = new ButtonModel(I18nTexts.modalCancel, 'outline white', this.modalServiceNg2.closeCurrentModal); - const saveButton: ButtonModel = new ButtonModel(I18nTexts.modalCreate, 'blue', this.createSubstitutionFilter, this.getDisabled); + const saveButton: ButtonModel = new ButtonModel(I18nTexts.modalCreate, 'blue', () => this.createSubstitutionFilter(constraintType), this.getDisabled); const modalModel: ModalModel = new ModalModel('l', I18nTexts.addSubstitutionFilterTxt, '', [saveButton, cancelButton], 'standard'); this.modalInstance = this.modalServiceNg2.createCustomModal(modalModel); this.modalServiceNg2.addDynamicContentToModal( @@ -181,27 +184,27 @@ export class SubstitutionFilterComponent { this.modalInstance.instance.open(); } - createSubstitutionFilter = (): void => { + createSubstitutionFilter = (constraintType: string) => { const newSubstitutionFilter: ConstraintObject = new ConstraintObject(this.modalInstance.instance.dynamicContent.instance.currentRule); this.isLoading = true; this.topologyTemplateService.createSubstitutionFilterConstraints( this.compositeService.uniqueId, - this.currentServiceInstance.uniqueId, newSubstitutionFilter, - this.compositeService.componentType + this.compositeService.componentType, + constraintType ).subscribe((response) => { - this.updateConstraintListEvent.emit(response.properties); + this.emitEventOnChanges(constraintType, response); this.isLoading = false; - }, () => { + }, (err) => { console.error("Failed to Create Substitution Filter on the component with id: ", this.compositeService.uniqueId); this.isLoading = false; }); this.modalServiceNg2.closeCurrentModal(); } - onSelectFilter(index: number) { + onSelectSubstitutionFilter(constraintType: string, index: number) { const cancelButton: ButtonModel = new ButtonModel(I18nTexts.modalCancel, 'outline white', this.modalServiceNg2.closeCurrentModal); - const updateButton: ButtonModel = new ButtonModel(I18nTexts.modalSave, 'blue', () => this.updateSubstitutionFilter(), this.getDisabled); + const updateButton: ButtonModel = new ButtonModel(I18nTexts.modalSave, 'blue', () => this.updateSubstitutionFilter(constraintType), this.getDisabled); const modalModel: ModalModel = new ModalModel('l', I18nTexts.updateSubstitutionFilterTxt, '', [updateButton, cancelButton], 'standard'); this.modalInstance = this.modalServiceNg2.createCustomModal(modalModel); this.modalServiceNg2.addDynamicContentToModal( @@ -209,7 +212,7 @@ export class SubstitutionFilterComponent { ServiceDependenciesEditorComponent, { serviceRuleIndex: index, - serviceRules: _.map(this.constraintObjects, (constraint) => new ConstraintObjectUI(constraint)), + serviceRules: _.map(this.constraintProperties, (constraint) => new ConstraintObjectUI(constraint)), currentServiceName: this.currentServiceInstance.name, operatorTypes: this.operatorTypes, compositeServiceName: this.compositeService.name, @@ -221,17 +224,16 @@ export class SubstitutionFilterComponent { this.modalInstance.instance.open(); } - updateSubstitutionFilter = (): void => { - const constraintToUpdate: ConstraintObject = this.modalInstance.instance.dynamicContent.instance.serviceRulesList.map((rule) => new ConstraintObject(rule)); + updateSubstitutionFilter = (constraintType: string): void => { + const constraintToUpdate: ConstraintObject[] = this.modalInstance.instance.dynamicContent.instance.serviceRulesList.map((rule) => new ConstraintObject(rule)); this.isLoading = true; this.topologyTemplateService.updateSubstitutionFilterConstraints( this.compositeService.uniqueId, - this.currentServiceInstance.uniqueId, constraintToUpdate, - this.compositeService.componentType + this.compositeService.componentType, + constraintType ).subscribe((response) => { - this.hasSubstitutionFilter.emit(this.isSubstitutionFilterSet()); - this.updateConstraintListEvent.emit(response.properties); + this.emitEventOnChanges(constraintType, response); this.isLoading = false; }, () => { console.error("Failed to Update Substitution Filter on the component with id: ", this.compositeService.uniqueId); @@ -240,22 +242,21 @@ export class SubstitutionFilterComponent { this.modalServiceNg2.closeCurrentModal(); } - onDeleteSubstitutionFilter = (index: number) => { + onDeleteSubstitutionFilter = (constraintType: string, index: number) => { this.isLoading = true; this.topologyTemplateService.deleteSubstitutionFilterConstraints( this.compositeService.uniqueId, - this.currentServiceInstance.uniqueId, index, - this.compositeService.componentType + this.compositeService.componentType, + constraintType ).subscribe((response) => { - console.log("on Delete - Response Properties: ", response.properties); - this.updateConstraintListEvent.emit(response.properties); + this.emitEventOnChanges(constraintType, response); this.isLoading = false; - }, () => { - console.error("Failed to Delete Substitution Filter on the component with id: ", this.compositeService.uniqueId); + }, (error) => { + console.error("Failed to Delete Substitution Filter on the component with id: ", + this.compositeService.uniqueId, error); this.isLoading = false; }); - this.constraintObjects = []; this.modalServiceNg2.closeCurrentModal(); } @@ -274,23 +275,15 @@ export class SubstitutionFilterComponent { } } - openDeleteModal = (index: number) => { + openDeleteModal = (constraintType: string, index: number) => { this.modalServiceNg2.createActionModal(I18nTexts.deleteSubstitutionFilterTxt, I18nTexts.deleteSubstitutionFilterMsg, - I18nTexts.modalDelete, () => this.onDeleteSubstitutionFilter(index), I18nTexts.modalCancel).instance.open(); + I18nTexts.modalDelete, () => this.onDeleteSubstitutionFilter(constraintType, index), I18nTexts.modalCancel).instance.open(); } - private getSubstitutionFilter = (componentInstance: ComponentInstance): void => { - this.topologyTemplateService.getSubstitutionFilterConstraints(this.compositeService.componentType, this.compositeService.uniqueId).subscribe((response) => { - const substitutionFilter: ConstraintObject[] = response.substitutionFilterForTopologyTemplate[componentInstance.uniqueId].properties; - if (substitutionFilter) { - this.currentServiceInstance = componentInstance; - this.constraintObjects = substitutionFilter; + private emitEventOnChanges(constraintType: string, response) { + if (ToscaFilterConstraintType.PROPERTIES === constraintType) { + this.updateSubstitutionFilterProperties.emit(response.properties); + this.constraintProperties = response.properties; } - }); - } - - private isSubstitutionFilterSet = (): boolean => { - return Array.isArray(this.constraintObjects) && this.constraintObjects.length > 0; } - } diff --git a/catalog-ui/src/app/ng2/components/logic/substitution-filter/substitution-filter.module.ts b/catalog-ui/src/app/ng2/components/logic/substitution-filter/substitution-filter.module.ts index 9ea7c0c5a0..34648f0931 100644 --- a/catalog-ui/src/app/ng2/components/logic/substitution-filter/substitution-filter.module.ts +++ b/catalog-ui/src/app/ng2/components/logic/substitution-filter/substitution-filter.module.ts @@ -22,6 +22,7 @@ import { NgModule } from '@angular/core'; import { UiElementsModule } from 'app/ng2/components/ui/ui-elements.module'; import { TranslateModule } from 'app/ng2/shared/translator/translate.module'; import { SubstitutionFilterComponent } from "./substitution-filter.component"; +import {AccordionModule} from "onap-ui-angular/dist/accordion/accordion.module"; @NgModule({ declarations: [ @@ -30,7 +31,8 @@ import { SubstitutionFilterComponent } from "./substitution-filter.component"; imports: [ CommonModule, UiElementsModule, - TranslateModule + TranslateModule, + AccordionModule ], exports: [ SubstitutionFilterComponent diff --git a/catalog-ui/src/app/ng2/pages/composition/panel/composition-panel.component.spec.ts b/catalog-ui/src/app/ng2/pages/composition/panel/composition-panel.component.spec.ts index 305086e8f3..75fab9abe7 100644 --- a/catalog-ui/src/app/ng2/pages/composition/panel/composition-panel.component.spec.ts +++ b/catalog-ui/src/app/ng2/pages/composition/panel/composition-panel.component.spec.ts @@ -108,7 +108,7 @@ describe('composition-panel component', () => { fixture.componentInstance.ngOnInit(); // Expect that - expect (fixture.componentInstance.tabs.length).toBe(5); + expect (fixture.componentInstance.tabs.length).toBe(6); expect (fixture.componentInstance.tabs[0]).toEqual(tabs.infoTab); expect (fixture.componentInstance.tabs[1]).toEqual(tabs.deploymentArtifacts); expect (fixture.componentInstance.tabs[2]).toEqual(tabs.inputs); @@ -157,7 +157,7 @@ describe('composition-panel component', () => { fixture.componentInstance.ngOnInit(); // Expect that - expect (fixture.componentInstance.tabs.length).toBe(6); + expect (fixture.componentInstance.tabs.length).toBe(5); expect (fixture.componentInstance.tabs[0]).toEqual(tabs.infoTab); expect (fixture.componentInstance.tabs[1]).toEqual(tabs.properties); expect (fixture.componentInstance.tabs[2]).toEqual(tabs.reqAndCapabilities); diff --git a/catalog-ui/src/app/ng2/pages/composition/panel/composition-panel.component.ts b/catalog-ui/src/app/ng2/pages/composition/panel/composition-panel.component.ts index 89634ef000..53c569be11 100644 --- a/catalog-ui/src/app/ng2/pages/composition/panel/composition-panel.component.ts +++ b/catalog-ui/src/app/ng2/pages/composition/panel/composition-panel.component.ts @@ -142,11 +142,11 @@ export class CompositionPanelComponent { if (component.isService() && !this.selectedComponentIsServiceProxyInstance() && !this.selectedComponentIsServiceSubstitutionInstance()) { this.tabs.push(tabs.apiArtifacts); + this.tabs.push(tabs.substitutionFilter); } if (component.isService() && (this.selectedComponentIsServiceProxyInstance() || this.selectedComponentIsServiceSubstitutionInstance())) { this.tabs.push(tabs.consumption); this.tabs.push(tabs.dependencies); - this.tabs.push(tabs.substitutionFilter) } else if (component.isResource() && this.selectedComponentIsVfcInstance()) { this.tabs.push(tabs.dependencies); } diff --git a/catalog-ui/src/app/ng2/pages/composition/panel/panel-tabs/substitution-filter-tab/substitution-filter-tab.component.html b/catalog-ui/src/app/ng2/pages/composition/panel/panel-tabs/substitution-filter-tab/substitution-filter-tab.component.html index d0656959f8..c8845deece 100644 --- a/catalog-ui/src/app/ng2/pages/composition/panel/panel-tabs/substitution-filter-tab/substitution-filter-tab.component.html +++ b/catalog-ui/src/app/ng2/pages/composition/panel/panel-tabs/substitution-filter-tab/substitution-filter-tab.component.html @@ -20,19 +20,15 @@ <ng2-expand-collapse state="0"> <header sdc-tooltip tooltip-text="{{input.title}}">{{input.title}}</header> - <content> - <div *ngIf="isComponentInstanceSelected"> - <substitution-filter - [compositeService]="metaData" - [currentServiceInstance]="component" - [selectedInstanceProperties]="selectedInstanceProperties" - [selectedInstanceSiblings]="selectedInstanceSiblings" - [selectedInstanceConstraints]="selectedInstanceConstraints" - [readonly]="isViewOnly" - (hasSubstitutionFilter)="notifyDependencyEventsObserver($event)" - (updateConstraintListEvent)="updateSelectedInstanceConstraints($event)" - (loadConstraintListEvent)="loadConstraints()"> - </substitution-filter> - </div> - </content> + <substitution-filter + [compositeService]="metaData" + [currentServiceInstance]="component" + [selectedInstanceProperties]="selectedInstanceProperties" + [selectedInstanceSiblings]="selectedInstanceSiblings" + [selectedInstanceConstraints]="selectedInstanceConstraints" + [readonly]="isViewOnly" + (hasSubstitutionFilter)="notifyDependencyEventsObserver($event)" + (updateConstraintListEvent)="updateSelectedInstanceConstraints($event)" + (loadConstraintListEvent)="loadConstraints()"> + </substitution-filter> </ng2-expand-collapse> diff --git a/catalog-ui/src/app/ng2/pages/composition/panel/panel-tabs/substitution-filter-tab/substitution-filter-tab.component.ts b/catalog-ui/src/app/ng2/pages/composition/panel/panel-tabs/substitution-filter-tab/substitution-filter-tab.component.ts index 20868e388b..2b5648c27f 100644 --- a/catalog-ui/src/app/ng2/pages/composition/panel/panel-tabs/substitution-filter-tab/substitution-filter-tab.component.ts +++ b/catalog-ui/src/app/ng2/pages/composition/panel/panel-tabs/substitution-filter-tab/substitution-filter-tab.component.ts @@ -20,14 +20,8 @@ import { Component, Input } from '@angular/core'; import { Store } from '@ngxs/store'; import { - CapabilitiesGroup, - Capability, Component as TopologyTemplate, - ComponentInstance, FullComponentInstance, - InputBEModel, - InputsGroup, - InterfaceModel, PropertiesGroup, PropertyBEModel, } from 'app/models'; @@ -73,8 +67,6 @@ export class SubstitutionFilterTabComponent { this.metaData = this.workspaceService.metadata; this.isComponentInstanceSelected = this.componentType === SelectedComponentType.COMPONENT_INSTANCE; this.initInstancesWithProperties(); - this.loadConstraints(); - this.initInstancesWithProperties(); } public loadConstraints = (): void => { @@ -93,13 +85,12 @@ export class SubstitutionFilterTabComponent { } private initInstancesWithProperties = (): void => { - this.topologyTemplateService.getComponentInstanceProperties(this.metaData.componentType, this.metaData.uniqueId).subscribe((genericResponse: ComponentGenericResponse) => { - this.componentInstanceProperties = genericResponse.componentInstancesProperties; + this.topologyTemplateService.getComponentPropertiesSubstitutionFilter(this.metaData.componentType, this.metaData.uniqueId).subscribe((genericResponse: ComponentGenericResponse) => { + this.selectedInstanceProperties = genericResponse.properties; this.updateInstanceAttributes(); }); } - private updateInstanceAttributes = (): void => { if (this.isComponentInstanceSelected && this.componentInstanceProperties) { const instancesMappedList = this.compositionService.componentInstances.map((coInstance) => new ServiceInstanceObject({ 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 01b8ead595..1933b3dba8 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 @@ -401,16 +401,20 @@ export class TopologyTemplateService { return this.http.delete<any>(this.baseUrl + this.getServerTypeUrl(componentType) + componentMetaDataId + '/resourceInstances/' + componentInstanceId + '/nodeFilter/' + constraintType + "/" + constraintIndex) } - createSubstitutionFilterConstraints(componentMetaDataId: string, componentInstanceId: string, constraint: ConstraintObject, componentType: string): Observable<any> { - return this.http.post<any>(this.baseUrl + this.getServerTypeUrl(componentType) + componentMetaDataId + '/resourceInstances/' + componentInstanceId + '/substitutionFilter', constraint); + getComponentPropertiesSubstitutionFilter(componentType: string, componentId: string): Observable<ComponentGenericResponse> { + return this.getComponentDataByFieldsName(componentType, componentId, [COMPONENT_FIELDS.COMPONENT_PROPERTIES]); } - updateSubstitutionFilterConstraints(componentMetaDataId: string, componentInstanceId: string, constraint: ConstraintObject, componentType: string): Observable<any> { - return this.http.put<any>(this.baseUrl + this.getServerTypeUrl(componentType) + componentMetaDataId + '/resourceInstances/' + componentInstanceId + '/substitutionFilter', constraint); + createSubstitutionFilterConstraints(componentMetaDataId: string, constraint: ConstraintObject, componentType: string, constraintType: string): Observable<any> { + return this.http.post<any>(this.baseUrl + this.getServerTypeUrl(componentType) + componentMetaDataId + '/substitutionFilter/' + constraintType, constraint); } - deleteSubstitutionFilterConstraints(componentMetaDataId: string, componentInstanceId: string, constraintIndex: number, componentType: string): Observable<any>{ - return this.http.delete<any>(this.baseUrl + this.getServerTypeUrl(componentType) + componentMetaDataId + '/resourceInstances/' + componentInstanceId + '/substitutionFilter/' + constraintIndex) + updateSubstitutionFilterConstraints(componentMetaDataId: string, constraint: ConstraintObject[], componentType: string, constraintType: string): Observable<any>{ + return this.http.put<any>(this.baseUrl + this.getServerTypeUrl(componentType) + componentMetaDataId + '/substitutionFilter/' + constraintType, constraint); + } + + deleteSubstitutionFilterConstraints(componentMetaDataId: string, constraintIndex: number, componentType: string, constraintType: string): Observable<any>{ + return this.http.delete<any>(this.baseUrl + this.getServerTypeUrl(componentType) + componentMetaDataId + '/substitutionFilter/' + constraintType + "/" + constraintIndex) } deletePolicy(component: Component, policy: PolicyInstance): Observable<PolicyInstance> { |