From 0d38a72c022fa93dba0bf052f893e51fb73d3552 Mon Sep 17 00:00:00 2001 From: "andre.schmid" Date: Thu, 8 Sep 2022 18:55:08 +0100 Subject: Support TOSCA functions in Node Capability Filters MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Adds support to use TOSCA functions as value in the node capability filters. Removes the current capability filter component to reuse, with a few changes, the node property filters component. Fixes problems with the edition and deletion of node capability filters. Change-Id: Ic91242d6cbc24e2ce0f60b84c63e104575bef8a9 Issue-ID: SDC-4173 Signed-off-by: André Schmid --- .../files/default/error-configuration.yaml | 152 +++++++------- .../impl/ComponentNodeFilterBusinessLogic.java | 12 +- .../components/impl/NodeFilterUploadCreator.java | 12 +- .../components/impl/utils/CINodeFilterUtils.java | 8 +- .../components/validation/NodeFilterValidator.java | 28 ++- .../be/servlets/ComponentNodeFilterServlet.java | 8 +- .../main/resources/config/error-configuration.yaml | 8 + .../impl/ComponentNodeFilterBusinessLogicTest.java | 14 +- .../servlets/ComponentNodeFilterServletTest.java | 32 +-- .../config/catalog-be/error-configuration.yaml | 8 + .../org/openecomp/sdc/be/dao/api/ActionStatus.java | 2 +- .../operations/NodeFilterOperation.java | 35 +++- .../operations/NodeFilterOperationTest.java | 77 ++++++-- .../src/app/models/capability-filter-constraint.ts | 61 ------ catalog-ui/src/app/models/filter-constraint.ts | 23 +++ .../app/models/ui-models/constraint-object-ui.ts | 26 --- .../ui-models/property-filter-constraint-ui.ts | 47 +++++ catalog-ui/src/app/ng2/app.module.ts | 35 ++-- .../service-dependencies.component.ts | 111 ++++++----- .../substitution-filter.component.ts | 50 ++--- .../dropdown/ui-element-dropdown.component.html | 2 +- ...ilities-filter-properties-editor.component.html | 81 -------- ...ilities-filter-properties-editor.component.less | 44 ----- ...abilities-filter-properties-editor.component.ts | 218 --------------------- ...capabilities-filter-properties-editor.module.ts | 46 ----- .../service-dependencies-tab.component.ts | 33 +++- .../service-dependencies-editor.component.html | 41 +++- .../service-dependencies-editor.component.ts | 205 ++++++++++++------- .../topology-template.service.ts | 6 +- .../src/app/utils/filter-constraint-helper.ts | 83 ++++---- catalog-ui/src/app/utils/tosca-function-helper.ts | 64 ++++++ catalog-ui/src/assets/languages/en_US.json | 1 + .../ci/tests/pages/ServiceDependenciesEditor.java | 8 +- 33 files changed, 739 insertions(+), 842 deletions(-) delete mode 100644 catalog-ui/src/app/models/capability-filter-constraint.ts delete mode 100644 catalog-ui/src/app/models/ui-models/constraint-object-ui.ts create mode 100644 catalog-ui/src/app/models/ui-models/property-filter-constraint-ui.ts delete mode 100644 catalog-ui/src/app/ng2/pages/composition/capabilities-filter-properties-editor/capabilities-filter-properties-editor.component.html delete mode 100644 catalog-ui/src/app/ng2/pages/composition/capabilities-filter-properties-editor/capabilities-filter-properties-editor.component.less delete mode 100644 catalog-ui/src/app/ng2/pages/composition/capabilities-filter-properties-editor/capabilities-filter-properties-editor.component.ts delete mode 100644 catalog-ui/src/app/ng2/pages/composition/capabilities-filter-properties-editor/capabilities-filter-properties-editor.module.ts create mode 100644 catalog-ui/src/app/utils/tosca-function-helper.ts diff --git a/catalog-be/src/main/docker/backend/chef-repo/cookbooks/sdc-catalog-be/files/default/error-configuration.yaml b/catalog-be/src/main/docker/backend/chef-repo/cookbooks/sdc-catalog-be/files/default/error-configuration.yaml index 7eb5ee47e9..7b3ade82c7 100644 --- a/catalog-be/src/main/docker/backend/chef-repo/cookbooks/sdc-catalog-be/files/default/error-configuration.yaml +++ b/catalog-be/src/main/docker/backend/chef-repo/cookbooks/sdc-catalog-be/files/default/error-configuration.yaml @@ -111,7 +111,7 @@ errors: message: "Error: Invalid userId '%1'.", messageId: "SVC4008" } -#---------SVC4009----------------------------- + #---------SVC4009----------------------------- USER_DEFINED: { code: 400, message: "Error: User Defined '%1'.", @@ -1436,10 +1436,10 @@ errors: message: "Error: artifact %1 is defined in CSAR %2 manifest but is not provided", messageId: "SVC4618" } -#---------SVC4619------------------------------ -# %1 - artifact name -# %2 - artifact type -# %3 - existing artifact type + #---------SVC4619------------------------------ + # %1 - artifact name + # %2 - artifact type + # %3 - existing artifact type ARTIFACT_ALREADY_EXIST_IN_DIFFERENT_TYPE_IN_CSAR: { code: 400, message: "Error: artifact %1 in type %2 already exists in type %3.", @@ -2012,29 +2012,29 @@ errors: #---------SVC4695----------------------------- # %1 - Interface Operation Name INTERFACE_OPERATION_NAME_ALREADY_IN_USE: { - code: 409, - message: "Error: Interface Operation name '%1' already in use, Your current changes will not be saved.", - messageId: "SVC4695" + code: 409, + message: "Error: Interface Operation name '%1' already in use, Your current changes will not be saved.", + messageId: "SVC4695" } #---------SVC4696----------------------------- # %1 - Interface Operation Name INTERFACE_OPERATION_NAME_INVALID: { - code: 400, - message: "Error: Interface Operation name '%1' is Invalid, Operation name should not contain special character, space and should not be greater than 200 characters.", - messageId: "SVC4696" + code: 400, + message: "Error: Interface Operation name '%1' is Invalid, Operation name should not contain special character, space and should not be greater than 200 characters.", + messageId: "SVC4696" } #---------SVC4697----------------------------- INTERFACE_OPERATION_NAME_MANDATORY: { - code: 400, - message: "Error: Interface Operation name is mandatory, Operation name can't be empty.", - messageId: "SVC4697" + code: 400, + message: "Error: Interface Operation name is mandatory, Operation name can't be empty.", + messageId: "SVC4697" } -#---------SVC4698----------------------------- -# %1 - Interface type + #---------SVC4698----------------------------- + # %1 - Interface type INTERFACE_OPERATION_INVALID_FOR_LOCAL_TYPE: { - code: 400, - message: "Error: Invalid input, only one operation is allowed in local interface type '%1'.", - messageId: "SVC4698" + code: 400, + message: "Error: Invalid input, only one operation is allowed in local interface type '%1'.", + messageId: "SVC4698" } #---------SVC4699----------------------------- # %1 - Interface Operation input parameter name @@ -2049,18 +2049,18 @@ errors: message: "Error: Interface operation input parameter name should not be empty.", messageId: "SVC4700" } -#---------SVC4701----------------------------- -# %1 - component Id + #---------SVC4701----------------------------- + # %1 - component Id INTERFACE_OPERATION_NOT_FOUND: { - code: 404, - message: "Error: Interface operation not found in the component '%1'.", - messageId: "SVC4701" + code: 404, + message: "Error: Interface operation not found in the component '%1'.", + messageId: "SVC4701" } #---------SVC4702----------------------------- INTERFACE_OPERATION_NOT_DELETED: { - code: 400, - message: "Error: Failed to delete interface operation.", - messageId: "SVC4702" + code: 400, + message: "Error: Failed to delete interface operation.", + messageId: "SVC4702" } #SVC4732 INTERFACE_UNKNOWN: { @@ -2131,32 +2131,32 @@ errors: message: "Error: CSAR packaging failed for %1 %2.", messageId: "SVC4706" } -#---------SVC4708----------------------------- -# %1 - Interface Operation input property name, component type + #---------SVC4708----------------------------- + # %1 - Interface Operation input property name, component type INTERFACE_OPERATION_INPUT_PROPERTY_NOT_FOUND_IN_COMPONENT: { code: 404, message: "Error: Interface operation input parameter property '%1' not found in '%2' input properties, capability properties or outputs of other operations.", messageId: "SVC4708" } -#---------SVC4709----------------------------- -# %1 - Interface Operation output parameter name + #---------SVC4709----------------------------- + # %1 - Interface Operation output parameter name INTERFACE_OPERATION_OUTPUT_NAME_ALREADY_IN_USE: { code: 400, message: "Error: Interface Operation output parameter name '%1' already in use, Your current changes will not be saved.", messageId: "SVC4708" } -#---------SVC4710----------------------------- + #---------SVC4710----------------------------- INTERFACE_OPERATION_OUTPUT_NAME_MANDATORY: { code: 400, message: "Error: Interface operation output parameter name should not be empty.", messageId: "SVC4710" } -#---------SVC4711----------------------------- -# %1 - interface Id + #---------SVC4711----------------------------- + # %1 - interface Id INTERFACE_NOT_FOUND_IN_COMPONENT: { - code: 404, - message: "Error: Interface not found in the component '%1'.", - messageId: "SVC4711" + code: 404, + message: "Error: Interface not found in the component '%1'.", + messageId: "SVC4711" } #---------SVC4709----------------------------- INVALID_PROPERTY_CONSTRAINTS: { @@ -2268,18 +2268,18 @@ errors: message: "Error: Missing value for the mandatory %1 property" , messageId: "SVC4721" } -#---------SVC4712----------------------------- + #---------SVC4712----------------------------- INTERFACE_LIFECYCLE_TYPES_NOT_FOUND: { - code: 404, - message: "Error: Interface Lifecycle types not found.", - messageId: "SVC4712" + code: 404, + message: "Error: Interface Lifecycle types not found.", + messageId: "SVC4712" } -#---------SVC4713----------------------------- -# %1 - Interface Operation Name + #---------SVC4713----------------------------- + # %1 - Interface Operation Name INTERFACE_OPERATION_INVALID_FOR_GLOBAL_TYPE: { - code: 400, - message: "Error: Invalid input, only pre-defined operation names are allowed in global interface type '%1'", - messageId: "SVC4713" + code: 400, + message: "Error: Invalid input, only pre-defined operation names are allowed in global interface type '%1'", + messageId: "SVC4713" } #---------SVC4714----------------------------- @@ -2345,89 +2345,89 @@ errors: messageId: "SVC4721" } - #---------SVC4722------------------------------ - # %1 Directive value set + #---------SVC4722------------------------------ + # %1 Directive value set DIRECTIVES_INVALID_VALUE: { - code: 404, - message: "Error: Invalid directive value : '%1' .", - messageId: "SVC4722" + code: 404, + message: "Error: Invalid directive value : '%1' .", + messageId: "SVC4722" } -#---------SVC4723----------------------------- -# %1 - Interface Operation output name + #---------SVC4723----------------------------- + # %1 - Interface Operation output name INTERFACE_OPERATION_MAPPED_OUTPUT_MODIFIED: { code: 400, message: "Error: Cannot update or delete interface operation output(s) '%1' mapped to an operation input", messageId: "SVC4723" } -#---------SVC4724----------------------------- -# %1 - Interface Operation output name + #---------SVC4724----------------------------- + # %1 - Interface Operation output name INTERFACE_OPERATION_DELETE_WITH_MAPPED_OUTPUT: { code: 400, message: "Error: Cannot delete interface operation with output(s) '%1' mapped to another operation input", messageId: "SVC4724" } -#---------SVC4725----------------------------- + #---------SVC4725----------------------------- INVALID_CONSUMPTION_TYPE: { code: 400, message: "Error: Given value is different than input type. Needs to be %1", messageId: "SVC4725" } -#---------SVC4726----------------------------- + #---------SVC4726----------------------------- INVALID_PROPERTY_VALUES: { code: 400, message: "Error: Invalid property values provided:\n %1", messageId: "SVC4726" } -#---------SVC4727------------------------------ + #---------SVC4727------------------------------ INVALID_PROPERTY_NAME: { code: 400, message: "Error: Property name contains invalid characters. It should have only letters, numbers and underscores.", messageId: "SVC4727" } -#---------SVC4728------------------------------ + #---------SVC4728------------------------------ FAILED_TO_CREATE_OR_UPDATE_CAPABILITY_PROPERTIES: { code: 500, message: "Error: Failed to create or update capabilities properties", messageId: "SVC4728" } -#---------SVC4729------------------------------ + #---------SVC4729------------------------------ # %1 - resource Id CAPABILITY_PROPERTIES_NOT_FOUND: { code: 400, message: "Error: Capability properties not found in the resource '%1'.", messageId: "SVC4729" } -#---------SVC4730------------------------------ + #---------SVC4730------------------------------ # %1 - property name PROPERTY_EXCEEDS_LIMIT: { - code: 400, - message: "Error: Invalid Content. %1 exceeds limit.", - messageId: "SVC4722" + code: 400, + message: "Error: Invalid Content. %1 exceeds limit.", + messageId: "SVC4722" } -#---------SVC4731------------------------------ + #---------SVC4731------------------------------ INVALID_PROPERY: { # %1 - property name - code: 400, - message: 'Error: Invalid Content. %1 has invalid format.', - messageId: "SVC4723" + code: 400, + message: 'Error: Invalid Content. %1 has invalid format.', + messageId: "SVC4723" } -#---------SVC4734------------------------------ + #---------SVC4734------------------------------ # %1 - list of validation errors INVALID_PM_DICTIONARY_FILE: { code: 400, message: 'Error: Invalid PM Dictionary File. %1', messageId: "SVC4734" } -#-----------SVC4735--------------------------- + #-----------SVC4735--------------------------- #%1 - input name INPUT_ALREADY_EXIST: { code: 409, message: "Error: Input with '%1' name already exists.", messageId: "SVC4735" } -#---------SVC4736------------------------------ + #---------SVC4736------------------------------ INVALID_INPUT_NAME: { code: 400, message: "Error: Input name contains invalid characters. It should have only letters, numbers and underscores.", @@ -2548,7 +2548,7 @@ errors: messageId: "SVC4153" } - #-----------SVC4154--------------------------- + #-----------SVC4154--------------------------- # %1 - "Model name" UNKNOWN_MODEL_TYPE: { code: 400, @@ -2813,3 +2813,11 @@ errors: code: 400 message: "Invalid component type '%1'. Expected types are: %2" messageId: "SVC4185" + + # %1 - The capability name + # %2 - The component type + # %3 - The component name + CAPABILITY_NOT_FOUND_IN_COMPONENT: + code: 400 + message: "Capability '%1' not found in '%2' '%3'." + messageId: "SVC4186" \ No newline at end of file diff --git a/catalog-be/src/main/java/org/openecomp/sdc/be/components/impl/ComponentNodeFilterBusinessLogic.java b/catalog-be/src/main/java/org/openecomp/sdc/be/components/impl/ComponentNodeFilterBusinessLogic.java index ff65d84416..457f43865f 100644 --- a/catalog-be/src/main/java/org/openecomp/sdc/be/components/impl/ComponentNodeFilterBusinessLogic.java +++ b/catalog-be/src/main/java/org/openecomp/sdc/be/components/impl/ComponentNodeFilterBusinessLogic.java @@ -52,7 +52,6 @@ import org.openecomp.sdc.be.model.operations.api.IGroupTypeOperation; import org.openecomp.sdc.be.model.operations.api.StorageOperationStatus; import org.openecomp.sdc.be.model.operations.impl.InterfaceLifecycleOperation; import org.openecomp.sdc.be.ui.mapper.FilterConstraintMapper; -import org.openecomp.sdc.be.ui.model.UIConstraint; import org.openecomp.sdc.be.user.Role; import org.openecomp.sdc.common.log.wrappers.Logger; import org.openecomp.sdc.exception.ResponseFormat; @@ -156,8 +155,7 @@ public class ComponentNodeFilterBusinessLogic extends BaseBusinessLogic { public Optional addNodeFilter(final String componentId, final String componentInstanceId, final FilterConstraintDto filterConstraint, final boolean shouldLock, final ComponentTypeEnum componentTypeEnum, - final NodeFilterConstraintType nodeFilterConstraintType, - final String capabilityName) throws BusinessLogicException { + final NodeFilterConstraintType nodeFilterConstraintType) throws BusinessLogicException { final Component component = getComponent(componentId); validateNodeFilter(component, componentInstanceId, filterConstraint); CINodeFilterDataDefinition nodeFilterDataDefinition = getComponentInstanceNodeFilterOrThrow(componentInstanceId, component); @@ -171,7 +169,7 @@ public class ComponentNodeFilterBusinessLogic extends BaseBusinessLogic { filterPropertyDataDefinition.setName(filterConstraint.getPropertyName()); filterPropertyDataDefinition.setConstraints(List.of(new FilterConstraintMapper().mapTo(filterConstraint))); final Either result = addNodeFilter(componentId, componentInstanceId, - nodeFilterConstraintType, nodeFilterDataDefinition, filterPropertyDataDefinition, capabilityName); + nodeFilterConstraintType, nodeFilterDataDefinition, filterPropertyDataDefinition, filterConstraint.getCapabilityName()); if (result.isRight()) { throw new BusinessLogicException(componentsUtils.getResponseFormatByResource( componentsUtils.convertFromStorageResponse(result.right().value()), component.getSystemName() @@ -290,7 +288,7 @@ public class ComponentNodeFilterBusinessLogic extends BaseBusinessLogic { } public Optional updateNodeFilter(final String componentId, final String componentInstanceId, - final UIConstraint uiConstraint, final ComponentTypeEnum componentTypeEnum, + final FilterConstraintDto filterConstraintDto, final ComponentTypeEnum componentTypeEnum, final NodeFilterConstraintType nodeFilterConstraintType, final int index) throws BusinessLogicException { final Optional deleteActionResponse = @@ -299,8 +297,8 @@ public class ComponentNodeFilterBusinessLogic extends BaseBusinessLogic { throw new BusinessLogicException( componentsUtils.getResponseFormat(ActionStatus.GENERAL_ERROR, "Failed to delete node filter capabilities")); } - return addNodeFilter(componentId.toLowerCase(), componentInstanceId, new FilterConstraintMapper().mapFrom(uiConstraint), true, - componentTypeEnum, nodeFilterConstraintType, uiConstraint.getCapabilityName()); + return addNodeFilter(componentId.toLowerCase(), componentInstanceId, filterConstraintDto, true, + componentTypeEnum, nodeFilterConstraintType); } public StorageOperationStatus associateNodeFilterToComponentInstance(final String componentId, diff --git a/catalog-be/src/main/java/org/openecomp/sdc/be/components/impl/NodeFilterUploadCreator.java b/catalog-be/src/main/java/org/openecomp/sdc/be/components/impl/NodeFilterUploadCreator.java index f34091de0f..9cdf07c15f 100644 --- a/catalog-be/src/main/java/org/openecomp/sdc/be/components/impl/NodeFilterUploadCreator.java +++ b/catalog-be/src/main/java/org/openecomp/sdc/be/components/impl/NodeFilterUploadCreator.java @@ -19,7 +19,6 @@ import java.util.ArrayList; import java.util.HashMap; import java.util.List; import java.util.Map; -import java.util.stream.Collectors; import org.onap.sdc.tosca.services.YamlUtil; import org.openecomp.sdc.be.model.UploadNodeFilterCapabilitiesInfo; import org.openecomp.sdc.be.model.UploadNodeFilterInfo; @@ -59,16 +58,13 @@ public class NodeFilterUploadCreator { final Map.Entry entry = map.entrySet().iterator().next(); final Object propertyConstraintClauses = entry.getValue(); if (propertyConstraintClauses instanceof Map) { - final List propertyFilterConstraintList = new ArrayList<>(); - propertyFilterConstraintList.add(valueToProperty(map)); - retVal.add(new UploadNodeFilterPropertyInfo(entry.getKey(), propertyFilterConstraintList)); + retVal.add(new UploadNodeFilterPropertyInfo(entry.getKey(), List.of(valueToProperty(map)))); } else if (propertyConstraintClauses instanceof List) { - final List propertyFilterConstraintList = ((List) propertyConstraintClauses).stream() + ((List) propertyConstraintClauses).stream() .map(propertyConstraintClause -> Map.of(entry.getKey(), propertyConstraintClause)) .map(this::valueToProperty) - .collect(Collectors.toList()); - - retVal.add(new UploadNodeFilterPropertyInfo(entry.getKey(), propertyFilterConstraintList)); + .map(filterConstraint -> new UploadNodeFilterPropertyInfo(entry.getKey(), List.of(filterConstraint))) + .forEach(retVal::add); } } return retVal; diff --git a/catalog-be/src/main/java/org/openecomp/sdc/be/components/impl/utils/CINodeFilterUtils.java b/catalog-be/src/main/java/org/openecomp/sdc/be/components/impl/utils/CINodeFilterUtils.java index 5ac9bcd2de..6f0472df61 100644 --- a/catalog-be/src/main/java/org/openecomp/sdc/be/components/impl/utils/CINodeFilterUtils.java +++ b/catalog-be/src/main/java/org/openecomp/sdc/be/components/impl/utils/CINodeFilterUtils.java @@ -60,15 +60,16 @@ public class CINodeFilterUtils { private RequirementNodeFilterCapabilityDataDefinition convertCapability(UploadNodeFilterCapabilitiesInfo capability) { RequirementNodeFilterCapabilityDataDefinition retVal = new RequirementNodeFilterCapabilityDataDefinition(); retVal.setName(capability.getName()); - List props = capability.getProperties().stream().map(this::buildProperty) + List propertyFilterList = capability.getProperties().stream() + .map(filterPropertyInfo -> buildProperty(capability.getName(), filterPropertyInfo)) .collect(Collectors.toList()); ListDataDefinition propsList = new ListDataDefinition<>(); - propsList.getListToscaDataDefinition().addAll(props); + propsList.getListToscaDataDefinition().addAll(propertyFilterList); retVal.setProperties(propsList); return retVal; } - private PropertyFilterDataDefinition buildProperty(final UploadNodeFilterPropertyInfo uploadNodeFilterPropertyInfo) { + private PropertyFilterDataDefinition buildProperty(final String capabilityName, final UploadNodeFilterPropertyInfo uploadNodeFilterPropertyInfo) { final var propertyFilter = new PropertyFilterDataDefinition(); propertyFilter.setName(uploadNodeFilterPropertyInfo.getName()); final List propertyConstraints = uploadNodeFilterPropertyInfo.getValues(); @@ -76,6 +77,7 @@ public class CINodeFilterUtils { propertyFilter.setConstraints( propertyConstraints.stream() .map(PropertyFilterConstraintDataDefinitionHelper::convertLegacyConstraint) + .peek(propertyFilterConstraintDataDefinition -> propertyFilterConstraintDataDefinition.setCapabilityName(capabilityName)) .collect(Collectors.toList()) ); } 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 12b58ded4a..b7b2452189 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 @@ -21,6 +21,7 @@ package org.openecomp.sdc.be.components.validation; import com.google.gson.Gson; import fj.data.Either; +import java.util.Collection; import java.util.List; import java.util.Map; import java.util.Optional; @@ -31,6 +32,7 @@ import org.apache.commons.lang3.StringUtils; import org.openecomp.sdc.be.dao.api.ActionStatus; import org.openecomp.sdc.be.dao.janusgraph.JanusGraphOperationStatus; import org.openecomp.sdc.be.datatypes.elements.ToscaGetFunctionDataDefinition; +import org.openecomp.sdc.be.datatypes.enums.PropertyFilterTargetType; import org.openecomp.sdc.be.datatypes.enums.PropertySource; import org.openecomp.sdc.be.impl.ComponentsUtils; import org.openecomp.sdc.be.model.CapabilityDefinition; @@ -290,11 +292,31 @@ public class NodeFilterValidator { findSubProperty(propertyPathFromSource.subList(1, propertyPathFromSource.size()), sourceSelectedProperty.get().getType(), allDataTypesEither.left().value()); } - final Optional targetComponentInstanceProperty = - parentComponent.getComponentInstancesProperties() - .get(componentInstanceId).stream() + final Optional targetComponentInstanceProperty; + if (PropertyFilterTargetType.CAPABILITY.equals(filterConstraint.getTargetType())) { + final CapabilityDefinition capability = parentComponent.getComponentInstances().stream() + .filter(componentInstance -> componentInstance.getUniqueId().equals(componentInstanceId)) + .map(componentInstance -> componentInstance.getCapabilities().values()) + .flatMap(Collection::stream) + .flatMap(Collection::stream) + .filter(capabilityDefinition -> capabilityDefinition.getName().equals(filterConstraint.getCapabilityName())) + .findFirst().orElse(null); + if (capability == null) { + return Either.right( + componentsUtils.getResponseFormat(ActionStatus.CAPABILITY_NOT_FOUND_IN_COMPONENT, + filterConstraint.getCapabilityName(), parentComponent.getComponentType().getValue(), parentComponent.getName()) + ); + } + targetComponentInstanceProperty = capability.getProperties().stream() .filter(property -> filterConstraint.getPropertyName().equals(property.getName())) .findFirst(); + } else { + targetComponentInstanceProperty = + parentComponent.getComponentInstancesProperties() + .get(componentInstanceId).stream() + .filter(property -> filterConstraint.getPropertyName().equals(property.getName())) + .findFirst(); + } if (sourceSelectedProperty.isPresent() && targetComponentInstanceProperty.isPresent()) { final ResponseFormat responseFormat = validatePropertyData(sourceSelectedProperty.get(), targetComponentInstanceProperty.get()); if (responseFormat != null) { diff --git a/catalog-be/src/main/java/org/openecomp/sdc/be/servlets/ComponentNodeFilterServlet.java b/catalog-be/src/main/java/org/openecomp/sdc/be/servlets/ComponentNodeFilterServlet.java index 80c806f9c3..d69a7d367c 100644 --- a/catalog-be/src/main/java/org/openecomp/sdc/be/servlets/ComponentNodeFilterServlet.java +++ b/catalog-be/src/main/java/org/openecomp/sdc/be/servlets/ComponentNodeFilterServlet.java @@ -42,7 +42,6 @@ import javax.ws.rs.core.Context; import javax.ws.rs.core.MediaType; import javax.ws.rs.core.Response; import org.apache.commons.collections4.CollectionUtils; -import org.apache.commons.lang3.StringUtils; import org.openecomp.sdc.be.components.impl.ComponentInstanceBusinessLogic; import org.openecomp.sdc.be.components.impl.ComponentNodeFilterBusinessLogic; import org.openecomp.sdc.be.components.impl.ResourceImportManager; @@ -140,8 +139,7 @@ public class ComponentNodeFilterServlet extends AbstractValidationsServlet { final FilterConstraintDto filterConstraintDto = new FilterConstraintMapper().mapFrom(uiConstraint); final Optional actionResponse = componentNodeFilterBusinessLogic .addNodeFilter(componentId.toLowerCase(), componentInstanceId, - filterConstraintDto, true, componentTypeEnum, nodeFilterConstraintType.get(), - StringUtils.isEmpty(uiConstraint.getCapabilityName()) ? "" : uiConstraint.getCapabilityName()); + filterConstraintDto, true, componentTypeEnum, nodeFilterConstraintType.get()); if (actionResponse.isEmpty()) { LOGGER.error(FAILED_TO_CREATE_NODE_FILTER); return buildErrorResponse(getComponentsUtils().getResponseFormat(ActionStatus.GENERAL_ERROR)); @@ -201,8 +199,8 @@ public class ComponentNodeFilterServlet extends AbstractValidationsServlet { } final NodeFilterConstraintType nodeFilterConstraintType = nodeFilterConstraintTypeOptional.get(); final Optional actionResponse = componentNodeFilterBusinessLogic - .updateNodeFilter(componentId.toLowerCase(), componentInstanceId, uiConstraint, componentTypeEnum, nodeFilterConstraintType, - index); + .updateNodeFilter(componentId.toLowerCase(), componentInstanceId, new FilterConstraintMapper().mapFrom(uiConstraint), + componentTypeEnum, nodeFilterConstraintType, index); if (actionResponse.isEmpty()) { LOGGER.error(FAILED_TO_UPDATE_NODE_FILTER); return buildErrorResponse(getComponentsUtils().getResponseFormat(ActionStatus.GENERAL_ERROR)); diff --git a/catalog-be/src/main/resources/config/error-configuration.yaml b/catalog-be/src/main/resources/config/error-configuration.yaml index 81e302f8bd..d31d4a6203 100644 --- a/catalog-be/src/main/resources/config/error-configuration.yaml +++ b/catalog-be/src/main/resources/config/error-configuration.yaml @@ -2813,3 +2813,11 @@ errors: code: 400 message: "Invalid component type '%1'. Expected types are: %2" messageId: "SVC4185" + + # %1 - The capability name + # %2 - The component type + # %3 - The component name + CAPABILITY_NOT_FOUND_IN_COMPONENT: + code: 400 + message: "Capability '%1' not found in '%2' '%3'." + messageId: "SVC4186" \ No newline at end of file diff --git a/catalog-be/src/test/java/org/openecomp/sdc/be/components/impl/ComponentNodeFilterBusinessLogicTest.java b/catalog-be/src/test/java/org/openecomp/sdc/be/components/impl/ComponentNodeFilterBusinessLogicTest.java index 1bf075e2f6..e3e173571e 100644 --- a/catalog-be/src/test/java/org/openecomp/sdc/be/components/impl/ComponentNodeFilterBusinessLogicTest.java +++ b/catalog-be/src/test/java/org/openecomp/sdc/be/components/impl/ComponentNodeFilterBusinessLogicTest.java @@ -274,7 +274,7 @@ class ComponentNodeFilterBusinessLogicTest extends BaseBusinessLogicMock { final Optional result = componentNodeFilterBusinessLogic .addNodeFilter(componentId, componentInstanceId, filterConstraintDto, true, ComponentTypeEnum.RESOURCE, - NodeFilterConstraintType.PROPERTIES, null); + NodeFilterConstraintType.PROPERTIES); assertThat(result).isPresent(); assertThat(result.get().getProperties().getListToscaDataDefinition()).hasSize(1); @@ -305,7 +305,7 @@ class ComponentNodeFilterBusinessLogicTest extends BaseBusinessLogicMock { final Optional result = componentNodeFilterBusinessLogic .addNodeFilter(componentId, componentInstanceId, filterConstraintDto, true, ComponentTypeEnum.RESOURCE, - NodeFilterConstraintType.CAPABILITIES, capabilityName + NodeFilterConstraintType.CAPABILITIES ); assertThat(result).isPresent(); @@ -342,7 +342,7 @@ class ComponentNodeFilterBusinessLogicTest extends BaseBusinessLogicMock { final BusinessLogicException businessLogicException = assertThrows(BusinessLogicException.class, () -> componentNodeFilterBusinessLogic .addNodeFilter(componentId, componentInstanceId, filterConstraintDto, true, ComponentTypeEnum.RESOURCE, - NodeFilterConstraintType.PROPERTIES, capabilityName)); + NodeFilterConstraintType.PROPERTIES)); assertEquals(expectedResponse, businessLogicException.getResponseFormat()); verify(toscaOperationFacade, times(1)).getToscaElement(componentId); @@ -370,7 +370,7 @@ class ComponentNodeFilterBusinessLogicTest extends BaseBusinessLogicMock { final BusinessLogicException businessLogicException = assertThrows(BusinessLogicException.class, () -> componentNodeFilterBusinessLogic .addNodeFilter(componentId, componentInstanceId, filterConstraintDto, true, ComponentTypeEnum.RESOURCE, - NodeFilterConstraintType.PROPERTIES, capabilityName)); + NodeFilterConstraintType.PROPERTIES)); assertEquals(expectedResponse, businessLogicException.getResponseFormat()); } @@ -473,7 +473,7 @@ class ComponentNodeFilterBusinessLogicTest extends BaseBusinessLogicMock { .thenReturn(StorageOperationStatus.OK); final Optional updateNodeFilterResult = componentNodeFilterBusinessLogic - .updateNodeFilter(componentId, componentInstanceId, uiConstraint, ComponentTypeEnum.RESOURCE, + .updateNodeFilter(componentId, componentInstanceId, filterConstraintDto, ComponentTypeEnum.RESOURCE, NodeFilterConstraintType.PROPERTIES, 0); assertThat(updateNodeFilterResult).isPresent(); @@ -505,7 +505,7 @@ class ComponentNodeFilterBusinessLogicTest extends BaseBusinessLogicMock { .thenReturn(StorageOperationStatus.OK); assertThrows(BusinessLogicException.class, () -> componentNodeFilterBusinessLogic - .updateNodeFilter(componentId, componentInstanceId, uiConstraint, ComponentTypeEnum.RESOURCE, + .updateNodeFilter(componentId, componentInstanceId, filterConstraintDto, ComponentTypeEnum.RESOURCE, NodeFilterConstraintType.PROPERTIES, 0)); } @@ -516,7 +516,7 @@ class ComponentNodeFilterBusinessLogicTest extends BaseBusinessLogicMock { .thenReturn(Either.left(true)); assertThrows(BusinessLogicException.class, () -> componentNodeFilterBusinessLogic - .updateNodeFilter(componentId, componentInstanceId, uiConstraint, ComponentTypeEnum.RESOURCE, + .updateNodeFilter(componentId, componentInstanceId, filterConstraintDto, ComponentTypeEnum.RESOURCE, NodeFilterConstraintType.PROPERTIES, 0)); verify(toscaOperationFacade, times(1)).getToscaElement(componentId); diff --git a/catalog-be/src/test/java/org/openecomp/sdc/be/servlets/ComponentNodeFilterServletTest.java b/catalog-be/src/test/java/org/openecomp/sdc/be/servlets/ComponentNodeFilterServletTest.java index 49252109cd..29e3a54133 100644 --- a/catalog-be/src/test/java/org/openecomp/sdc/be/servlets/ComponentNodeFilterServletTest.java +++ b/catalog-be/src/test/java/org/openecomp/sdc/be/servlets/ComponentNodeFilterServletTest.java @@ -202,7 +202,7 @@ class ComponentNodeFilterServletTest extends JerseyTest { doReturn(Optional.of(ciNodeFilterDataDefinition)).when(componentNodeFilterBusinessLogic) .addNodeFilter(componentId, componentInstance, filterConstraintDto, true, ComponentTypeEnum.RESOURCE, - NodeFilterConstraintType.PROPERTIES, ""); + NodeFilterConstraintType.PROPERTIES); final Response response = target() .path(path) @@ -212,7 +212,7 @@ class ComponentNodeFilterServletTest extends JerseyTest { verify(componentNodeFilterBusinessLogic, times(1)) .addNodeFilter(anyString(), anyString(), any(FilterConstraintDto.class), anyBoolean(), any(ComponentTypeEnum.class), - any(NodeFilterConstraintType.class), anyString() + any(NodeFilterConstraintType.class) ); assertThat(response.getStatus()).isEqualTo(HttpStatus.OK_200); @@ -238,7 +238,7 @@ class ComponentNodeFilterServletTest extends JerseyTest { final FilterConstraintDto filterConstraintDto1 = new FilterConstraintMapper().mapFrom(uiConstraint1); when(componentNodeFilterBusinessLogic .addNodeFilter(componentId, componentInstance, filterConstraintDto1, true, ComponentTypeEnum.RESOURCE, - NodeFilterConstraintType.CAPABILITIES, capabilityName) + NodeFilterConstraintType.CAPABILITIES) ).thenReturn(Optional.of(ciNodeFilterDataDefinition)); final Response response = target() .path(path) @@ -248,14 +248,14 @@ class ComponentNodeFilterServletTest extends JerseyTest { verify(componentNodeFilterBusinessLogic, times(1)) .addNodeFilter(componentId, componentInstance, filterConstraintDto1, true, ComponentTypeEnum.RESOURCE, - NodeFilterConstraintType.CAPABILITIES, capabilityName); + NodeFilterConstraintType.CAPABILITIES); assertThat(response.getStatus()).isEqualTo(HttpStatus.OK_200); verify(componentNodeFilterBusinessLogic,times(1)).validateUser(USER_ID); } @Test - void addNodeFilterFailTest() throws BusinessLogicException, JsonProcessingException { + void addNodeFilterFailTest() { initComponentData(); final String pathFormat = V_1_CATALOG_S_S_COMPONENT_INSTANCE_S_S_NODE_FILTER; final String path = String.format(pathFormat, componentType, componentId, componentInstance, @@ -274,7 +274,7 @@ class ComponentNodeFilterServletTest extends JerseyTest { } @Test - void addNodeFilterFailConstraintParseTest() throws JsonProcessingException { + void addNodeFilterFailConstraintParseTest() { initComponentData(); final String pathFormat = V_1_CATALOG_S_S_COMPONENT_INSTANCE_S_S_NODE_FILTER; final String path = String.format(pathFormat, componentType, componentId, componentInstance, NodeFilterConstraintType.PROPERTIES_PARAM_NAME); @@ -292,7 +292,7 @@ class ComponentNodeFilterServletTest extends JerseyTest { } @Test - void addNodeFilterFailConvertTest() throws JsonProcessingException { + void addNodeFilterFailConvertTest() { initComponentData(); final String pathFormat = V_1_CATALOG_S_S_COMPONENT_INSTANCE_S_S_NODE_FILTER; final String path = String.format(pathFormat, componentType, componentId, componentInstance, @@ -311,7 +311,7 @@ class ComponentNodeFilterServletTest extends JerseyTest { } @Test - void updateNodeFilterPropertiesSuccessTest() throws BusinessLogicException, JsonProcessingException { + void updateNodeFilterPropertiesSuccessTest() throws BusinessLogicException { initComponentData(); final String pathFormat = V_1_CATALOG_S_S_COMPONENT_INSTANCE_S_S_S_NODE_FILTER; final String path = String.format(pathFormat, componentType, componentId, componentInstance, @@ -325,7 +325,7 @@ class ComponentNodeFilterServletTest extends JerseyTest { doReturn(Optional.of(uiConstraint)).when(componentsUtils) .parseToConstraint(anyString(), any(User.class), eq(ComponentTypeEnum.RESOURCE)); when(componentNodeFilterBusinessLogic - .updateNodeFilter(componentId, componentInstance, uiConstraint, ComponentTypeEnum.RESOURCE, + .updateNodeFilter(componentId, componentInstance, filterConstraintDto, ComponentTypeEnum.RESOURCE, NodeFilterConstraintType.PROPERTIES, 0)).thenReturn(Optional.of(ciNodeFilterDataDefinition)); final Response response = target() .path(path) @@ -338,7 +338,7 @@ class ComponentNodeFilterServletTest extends JerseyTest { } @Test - void updateNodeFilterCapabilitiesSuccessTest() throws BusinessLogicException, JsonProcessingException { + void updateNodeFilterCapabilitiesSuccessTest() throws BusinessLogicException { initComponentData(); final String pathFormat = V_1_CATALOG_S_S_COMPONENT_INSTANCE_S_S_S_NODE_FILTER; final String path = String.format(pathFormat, componentType, componentId, componentInstance, @@ -353,7 +353,7 @@ class ComponentNodeFilterServletTest extends JerseyTest { when(componentsUtils.getResponseFormat(ActionStatus.OK)).thenReturn(responseFormat); when(componentNodeFilterBusinessLogic - .updateNodeFilter(componentId, componentInstance, uiConstraint, + .updateNodeFilter(componentId, componentInstance, filterConstraintDto, ComponentTypeEnum.RESOURCE, NodeFilterConstraintType.CAPABILITIES, 0)) .thenReturn(Optional.of(ciNodeFilterDataDefinition)); @@ -364,7 +364,7 @@ class ComponentNodeFilterServletTest extends JerseyTest { .put(Entity.entity(inputJson, MediaType.APPLICATION_JSON)); verify(componentNodeFilterBusinessLogic, times(1)) - .updateNodeFilter(anyString(), anyString(), any(UIConstraint.class), + .updateNodeFilter(anyString(), anyString(), any(FilterConstraintDto.class), any(ComponentTypeEnum.class), any(NodeFilterConstraintType.class), anyInt()); @@ -373,7 +373,7 @@ class ComponentNodeFilterServletTest extends JerseyTest { } @Test - void updateNodeFilterFailTest() throws BusinessLogicException, JsonProcessingException { + void updateNodeFilterFailTest() { initComponentData(); final String pathFormat = V_1_CATALOG_S_S_COMPONENT_INSTANCE_S_S_S_NODE_FILTER; final String path = String.format(pathFormat, componentType, componentId, componentInstance, @@ -392,7 +392,7 @@ class ComponentNodeFilterServletTest extends JerseyTest { } @Test - void updateNodeFilterFailConstraintParseTest() throws JsonProcessingException { + void updateNodeFilterFailConstraintParseTest() { initComponentData(); final String pathFormat = V_1_CATALOG_S_S_COMPONENT_INSTANCE_S_S_S_NODE_FILTER; final String path = String.format(pathFormat, componentType, componentId, componentInstance, @@ -411,7 +411,7 @@ class ComponentNodeFilterServletTest extends JerseyTest { } @Test - void updateNodeFilterFailConvertTest() throws JsonProcessingException { + void updateNodeFilterFailConvertTest() { initComponentData(); final String pathFormat = V_1_CATALOG_S_S_COMPONENT_INSTANCE_S_S_S_NODE_FILTER; final String path = String.format(pathFormat, componentType, componentId, componentInstance, @@ -430,7 +430,7 @@ class ComponentNodeFilterServletTest extends JerseyTest { } @Test - void deleteNodeFilterSuccessTest() throws BusinessLogicException, JsonProcessingException { + void deleteNodeFilterSuccessTest() throws BusinessLogicException { initComponentData(); final String pathFormat = V_1_CATALOG_S_S_COMPONENT_INSTANCE_S_S_S_NODE_FILTER; final String path = String.format(pathFormat, componentType, componentId, componentInstance, diff --git a/catalog-be/src/test/resources/config/catalog-be/error-configuration.yaml b/catalog-be/src/test/resources/config/catalog-be/error-configuration.yaml index 81e302f8bd..d31d4a6203 100644 --- a/catalog-be/src/test/resources/config/catalog-be/error-configuration.yaml +++ b/catalog-be/src/test/resources/config/catalog-be/error-configuration.yaml @@ -2813,3 +2813,11 @@ errors: code: 400 message: "Invalid component type '%1'. Expected types are: %2" messageId: "SVC4185" + + # %1 - The capability name + # %2 - The component type + # %3 - The component name + CAPABILITY_NOT_FOUND_IN_COMPONENT: + code: 400 + message: "Capability '%1' not found in '%2' '%3'." + messageId: "SVC4186" \ No newline at end of file diff --git a/catalog-dao/src/main/java/org/openecomp/sdc/be/dao/api/ActionStatus.java b/catalog-dao/src/main/java/org/openecomp/sdc/be/dao/api/ActionStatus.java index 6208f11732..2f5f175a17 100644 --- a/catalog-dao/src/main/java/org/openecomp/sdc/be/dao/api/ActionStatus.java +++ b/catalog-dao/src/main/java/org/openecomp/sdc/be/dao/api/ActionStatus.java @@ -119,7 +119,7 @@ public enum ActionStatus { CONTAINER_CANNOT_CONTAIN_COMPONENT_IN_STATE, CONTAINER_CANNOT_CONTAIN_INSTANCE, MISSING_MANDATORY_PROPERTY, MANDATORY_PROPERTY_MISSING_VALUE, //Capability related CAPABILITY_NOT_FOUND, CAPABILITY_NAME_MANDATORY, CAPABILITY_TYPE_MANDATORY, CAPABILITY_NAME_ALREADY_IN_USE, MAX_OCCURRENCES_SHOULD_BE_GREATER_THAN_MIN_OCCURRENCES, CAPABILITY_DELETION_NOT_ALLOWED_USED_IN_COMPOSITION, CAPABILITY_UPDATE_NOT_ALLOWED_USED_IN_COMPOSITION, INVALID_CAPABILITY_NAME, FAILED_TO_CREATE_OR_UPDATE_CAPABILITY_PROPERTIES, CAPABILITY_PROPERTIES_NOT_FOUND, RELATIONSHIP_TYPE_ALREADY_EXIST, MISSING_RELATIONSHIP_TYPE, CAPABILITY_TYPE_CANNOT_BE_EMPTY, - COMPONENT_CAPABILITY_UPDATE_NOT_FOUND_ERROR, + COMPONENT_CAPABILITY_UPDATE_NOT_FOUND_ERROR, CAPABILITY_NOT_FOUND_IN_COMPONENT, //Requirement related REQUIREMENT_NOT_FOUND, REQUIREMENT_NAME_MANDATORY, REQUIREMENT_CAPABILITY_MANDATORY, REQUIREMENT_NAME_ALREADY_IN_USE, REQUIREMENT_DELETION_NOT_ALLOWED_USED_IN_COMPOSITION, REQUIREMENT_UPDATE_NOT_ALLOWED_USED_IN_COMPOSITION, INVALID_REQUIREMENT_NAME, //Abstract template related diff --git a/catalog-model/src/main/java/org/openecomp/sdc/be/model/jsonjanusgraph/operations/NodeFilterOperation.java b/catalog-model/src/main/java/org/openecomp/sdc/be/model/jsonjanusgraph/operations/NodeFilterOperation.java index 3dc2a73466..f1de061c9f 100644 --- a/catalog-model/src/main/java/org/openecomp/sdc/be/model/jsonjanusgraph/operations/NodeFilterOperation.java +++ b/catalog-model/src/main/java/org/openecomp/sdc/be/model/jsonjanusgraph/operations/NodeFilterOperation.java @@ -84,13 +84,9 @@ public class NodeFilterOperation extends BaseOperation { final int propertyIndex, final NodeFilterConstraintType nodeFilterConstraintType) { if (NodeFilterConstraintType.PROPERTIES.equals(nodeFilterConstraintType)) { - final ListDataDefinition properties = nodeFilterDataDefinition.getProperties(); - properties.getListToscaDataDefinition().remove(propertyIndex); - nodeFilterDataDefinition.setProperties(properties); + nodeFilterDataDefinition.getProperties().getListToscaDataDefinition().remove(propertyIndex); } else if (NodeFilterConstraintType.CAPABILITIES.equals(nodeFilterConstraintType)) { - final ListDataDefinition capabilities = nodeFilterDataDefinition.getCapabilities(); - capabilities.getListToscaDataDefinition().remove(propertyIndex); - nodeFilterDataDefinition.setCapabilities(capabilities); + removeCapabilityNodeFilterByIndex(nodeFilterDataDefinition, propertyIndex); } return addOrUpdateNodeFilter(true, serviceId, componentInstanceId, nodeFilterDataDefinition); } @@ -116,11 +112,11 @@ public class NodeFilterOperation extends BaseOperation { capabilities = new ListDataDefinition<>(); nodeFilterDataDefinition.setCapabilities(capabilities); } - + final Optional existingCap = capabilities .getListToscaDataDefinition().stream() .filter(def -> def.getName().equals(requirementNodeFilterCapabilityDataDefinition.getName())).findAny(); - + if (existingCap.isPresent()) { final ListDataDefinition newProperties = requirementNodeFilterCapabilityDataDefinition.getProperties(); final ListDataDefinition existingProperties = existingCap.get().getProperties(); @@ -144,6 +140,29 @@ public class NodeFilterOperation extends BaseOperation { return addOrUpdateNodeFilter(false, componentId, componentInstanceId, nodeFilterDataDefinition); } + private void removeCapabilityNodeFilterByIndex(final CINodeFilterDataDefinition nodeFilterDataDefinition, final int filterToRemoveIndex) { + int currentFilterCountdown = filterToRemoveIndex; + final List filtersByCapability = + nodeFilterDataDefinition.getCapabilities().getListToscaDataDefinition(); + for (final RequirementNodeFilterCapabilityDataDefinition capabilityFilterGroup : filtersByCapability) { + final List capabilityFilters = capabilityFilterGroup.getProperties().getListToscaDataDefinition(); + if (isFilterInCapabilityGroup(currentFilterCountdown, capabilityFilters)) { + capabilityFilters.remove(currentFilterCountdown); + break; + } else { + currentFilterCountdown = getRemainingFilterCount(currentFilterCountdown, capabilityFilters); + } + } + } + + private boolean isFilterInCapabilityGroup(int currentFilterCount, List capabilityFilters) { + return capabilityFilters.size() > currentFilterCount; + } + + private int getRemainingFilterCount(int currentFilterCount, final List capabilityFilters) { + return currentFilterCount - capabilityFilters.size(); + } + private Either addOrUpdateNodeFilter(final boolean isUpdateAction, final String componentId, final String componentInstanceId, final CINodeFilterDataDefinition ciNodeFilterDataDefinition) { diff --git a/catalog-model/src/test/java/org/openecomp/sdc/be/model/jsonjanusgraph/operations/NodeFilterOperationTest.java b/catalog-model/src/test/java/org/openecomp/sdc/be/model/jsonjanusgraph/operations/NodeFilterOperationTest.java index bd16016ad9..3df279511b 100644 --- a/catalog-model/src/test/java/org/openecomp/sdc/be/model/jsonjanusgraph/operations/NodeFilterOperationTest.java +++ b/catalog-model/src/test/java/org/openecomp/sdc/be/model/jsonjanusgraph/operations/NodeFilterOperationTest.java @@ -20,9 +20,22 @@ */ package org.openecomp.sdc.be.model.jsonjanusgraph.operations; +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertFalse; +import static org.junit.jupiter.api.Assertions.assertTrue; +import static org.mockito.ArgumentMatchers.any; +import static org.mockito.ArgumentMatchers.eq; +import static org.mockito.ArgumentMatchers.nullable; +import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.when; + import fj.data.Either; +import java.util.Arrays; +import java.util.HashMap; import java.util.List; import java.util.Map; +import org.apache.tinkerpop.gremlin.structure.Direction; +import org.apache.tinkerpop.gremlin.structure.Edge; import org.janusgraph.core.JanusGraphVertex; import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; @@ -37,22 +50,14 @@ import org.openecomp.sdc.be.datatypes.elements.CINodeFilterDataDefinition; import org.openecomp.sdc.be.datatypes.elements.ListDataDefinition; import org.openecomp.sdc.be.datatypes.elements.PropertyFilterConstraintDataDefinition; import org.openecomp.sdc.be.datatypes.elements.PropertyFilterDataDefinition; +import org.openecomp.sdc.be.datatypes.elements.RequirementNodeFilterCapabilityDataDefinition; import org.openecomp.sdc.be.datatypes.enums.ConstraintType; import org.openecomp.sdc.be.datatypes.enums.FilterValueType; +import org.openecomp.sdc.be.datatypes.enums.GraphPropertyEnum; +import org.openecomp.sdc.be.datatypes.enums.NodeFilterConstraintType; import org.openecomp.sdc.be.datatypes.enums.PropertyFilterTargetType; import org.openecomp.sdc.be.model.operations.api.StorageOperationStatus; -import java.util.Arrays; -import java.util.HashMap; - -import static org.junit.jupiter.api.Assertions.assertEquals; -import static org.junit.jupiter.api.Assertions.assertTrue; -import static org.mockito.ArgumentMatchers.any; -import static org.mockito.ArgumentMatchers.eq; -import static org.mockito.ArgumentMatchers.nullable; -import static org.mockito.Mockito.mock; -import static org.mockito.Mockito.when; - class NodeFilterOperationTest { private final NodeFilterOperation nodeFilterOperation = new NodeFilterOperation(); @@ -116,4 +121,54 @@ class NodeFilterOperationTest { assertEquals("new node filter name", expectedNodeFilter.getName()); assertEquals(listDataDefinition, expectedNodeFilter.getProperties()); } + + @Test + void deleteCapabilityConstraintTest() { + final var ciNodeFilterDataDefinition = new CINodeFilterDataDefinition(); + final var capabilities = new ListDataDefinition(); + + var capabilityFilter1 = new RequirementNodeFilterCapabilityDataDefinition(); + final var propertyFilterList = new ListDataDefinition(); + propertyFilterList.add(new PropertyFilterDataDefinition()); + propertyFilterList.add(new PropertyFilterDataDefinition()); + propertyFilterList.add(new PropertyFilterDataDefinition()); + propertyFilterList.add(new PropertyFilterDataDefinition()); + propertyFilterList.add(new PropertyFilterDataDefinition()); + propertyFilterList.add(new PropertyFilterDataDefinition()); + capabilityFilter1.setProperties(propertyFilterList); + capabilities.add(capabilityFilter1); + + var capabilityFilter2 = new RequirementNodeFilterCapabilityDataDefinition(); + final var propertyFilterList2 = new ListDataDefinition(); + final var filterToDelete = new PropertyFilterDataDefinition(); + propertyFilterList2.add(filterToDelete); + propertyFilterList2.add(new PropertyFilterDataDefinition()); + capabilityFilter2.setProperties(propertyFilterList2); + capabilities.add(capabilityFilter2); + + final GraphVertex serviceVertexMock = mock(GraphVertex.class); + final JanusGraphVertex serviceJanusVertex = mock(JanusGraphVertex.class); + when(serviceVertexMock.getVertex()).thenReturn(serviceJanusVertex); + when(serviceVertexMock.getUniqueId()).thenReturn("componentId"); + when(janusGraphDao.getVertexById("componentId", JsonParseFlagEnum.NoParse)).thenReturn(Either.left(serviceVertexMock)); + final GraphVertex nodeFilterVertexMock = mock(GraphVertex.class); + when(janusGraphDao.getChildVertex(serviceVertexMock, EdgeLabelEnum.NODE_FILTER_TEMPLATE, JsonParseFlagEnum.ParseJson)) + .thenReturn(Either.left(nodeFilterVertexMock)); + final JanusGraphVertex nodeFilterJanusVertexMock = mock(JanusGraphVertex.class); + when(nodeFilterVertexMock.getVertex()).thenReturn(nodeFilterJanusVertexMock); + final Edge edgeToDeleteMock = mock(Edge.class); + when(nodeFilterJanusVertexMock.edges(Direction.IN, EdgeLabelEnum.NODE_FILTER_TEMPLATE.name())) + .thenReturn(List.of(edgeToDeleteMock).iterator()); + when(janusGraphDao.getProperty(any(), eq(GraphPropertyEnum.UNIQUE_ID.getProperty()))).thenReturn("componentId"); + when(janusGraphDao.updateVertex(nodeFilterVertexMock)).thenReturn(Either.left(nodeFilterVertexMock)); + + ciNodeFilterDataDefinition.setCapabilities(capabilities); + final Either result = nodeFilterOperation.deleteConstraint( + "componentId", "instanceId", ciNodeFilterDataDefinition, 6, NodeFilterConstraintType.CAPABILITIES); + + assertTrue(result.isLeft()); + assertEquals(1, propertyFilterList2.getListToscaDataDefinition().size()); + assertFalse(propertyFilterList2.getListToscaDataDefinition().contains(filterToDelete)); + } + } \ No newline at end of file diff --git a/catalog-ui/src/app/models/capability-filter-constraint.ts b/catalog-ui/src/app/models/capability-filter-constraint.ts deleted file mode 100644 index 64d9913a54..0000000000 --- a/catalog-ui/src/app/models/capability-filter-constraint.ts +++ /dev/null @@ -1,61 +0,0 @@ -/* -* ============LICENSE_START======================================================= -* SDC -* ================================================================================ -* Copyright (C) 2020 Nordix Foundation. All rights reserved. -* ================================================================================ -* Licensed under the Apache License, Version 2.0 (the "License"); -* you may not use this file except in compliance with the License. -* You may obtain a copy of the License at -* -* http://www.apache.org/licenses/LICENSE-2.0 -* Unless required by applicable law or agreed to in writing, software -* distributed under the License is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* See the License for the specific language governing permissions and -* limitations under the License. -* -* SPDX-License-Identifier: Apache-2.0 -* ============LICENSE_END========================================================= -*/ - -export class CapabilityFilterConstraint { - capabilityName: string; - servicePropertyName: string; - constraintOperator: string; - sourceType: string; - sourceName: string; - value: string; - - constructor(input?: any) { - if (input) { - this.capabilityName = input.capabilityName; - this.servicePropertyName = input.servicePropertyName; - this.constraintOperator = input.constraintOperator; - this.sourceType = input.sourceType; - this.sourceName = input.sourceName; - this.value = input.value; - } - } -} - -export class CapabilityFilterConstraintUI extends CapabilityFilterConstraint { - isValidValue: boolean; - - constructor(input?: any) { - super(input); - if (input) { - this.isValidValue = input.isValidValue ? input.isValidValue : input.value !== ''; - } - } - - public updateValidity(isValidValue: boolean) { - this.isValidValue = isValidValue; - } - - public isValidRule(isStatic) { - const isValidValue = isStatic ? this.isValidValue : true; - return this.servicePropertyName != null && this.servicePropertyName !== '' - && this.value != null && this.value !== '' && isValidValue; - } -} diff --git a/catalog-ui/src/app/models/filter-constraint.ts b/catalog-ui/src/app/models/filter-constraint.ts index a118c97d7b..69ad90cb90 100644 --- a/catalog-ui/src/app/models/filter-constraint.ts +++ b/catalog-ui/src/app/models/filter-constraint.ts @@ -1,4 +1,26 @@ +/* + * - + * ============LICENSE_START======================================================= + * Copyright (C) 2022 Nordix Foundation. + * ================================================================================ + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + * SPDX-License-Identifier: Apache-2.0 + * ============LICENSE_END========================================================= + */ + export class FilterConstraint { + capabilityName: string; servicePropertyName: string; constraintOperator: string; sourceType: string; @@ -7,6 +29,7 @@ export class FilterConstraint { constructor(input?: any) { if (input) { + this.capabilityName = input.capabilityName; this.servicePropertyName = input.servicePropertyName; this.constraintOperator = input.constraintOperator; this.sourceType = input.sourceType; diff --git a/catalog-ui/src/app/models/ui-models/constraint-object-ui.ts b/catalog-ui/src/app/models/ui-models/constraint-object-ui.ts deleted file mode 100644 index 48cf2abdc6..0000000000 --- a/catalog-ui/src/app/models/ui-models/constraint-object-ui.ts +++ /dev/null @@ -1,26 +0,0 @@ -import {FilterConstraint} from "../filter-constraint"; - -export class ConstraintObjectUI extends FilterConstraint { - isValidValue: boolean; - - constructor(input?: any) { - super(input); - if (input) { - this.isValidValue = input.isValidValue ? input.isValidValue : input.value !== ''; - } - } - - public updateValidity(isValidValue: boolean) { - this.isValidValue = isValidValue; - } - - public isValidRule() { - const isValidValue = this.isStatic() ? this.isValidValue : true; - return this.servicePropertyName != null && this.servicePropertyName !== '' - && this.value != null && this.value !== '' && isValidValue; - } - - private isStatic() { - return this.sourceName === 'static'; - } -} \ No newline at end of file diff --git a/catalog-ui/src/app/models/ui-models/property-filter-constraint-ui.ts b/catalog-ui/src/app/models/ui-models/property-filter-constraint-ui.ts new file mode 100644 index 0000000000..f47677bf5a --- /dev/null +++ b/catalog-ui/src/app/models/ui-models/property-filter-constraint-ui.ts @@ -0,0 +1,47 @@ +/* + * - + * ============LICENSE_START======================================================= + * Copyright (C) 2022 Nordix Foundation. + * ================================================================================ + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + * SPDX-License-Identifier: Apache-2.0 + * ============LICENSE_END========================================================= + */ + +import {FilterConstraint} from "../filter-constraint"; + +export class PropertyFilterConstraintUi extends FilterConstraint { + isValidValue: boolean; + + constructor(input?: any) { + super(input); + if (input) { + this.isValidValue = input.isValidValue ? input.isValidValue : input.value !== ''; + } + } + + public updateValidity(isValidValue: boolean) { + this.isValidValue = isValidValue; + } + + public isValidRule() { + const isValidValue = this.isStatic() ? this.isValidValue : true; + return this.servicePropertyName != null && this.servicePropertyName !== '' + && this.value != null && this.value !== '' && isValidValue; + } + + private isStatic() { + return this.sourceName === 'static'; + } +} \ No newline at end of file diff --git a/catalog-ui/src/app/ng2/app.module.ts b/catalog-ui/src/app/ng2/app.module.ts index 707e328a52..7153f0a841 100644 --- a/catalog-ui/src/app/ng2/app.module.ts +++ b/catalog-ui/src/app/ng2/app.module.ts @@ -20,18 +20,22 @@ import {BrowserAnimationsModule} from '@angular/platform-browser/animations'; import {BrowserModule} from '@angular/platform-browser'; -import { NgModule, APP_INITIALIZER } from '@angular/core'; +import {APP_INITIALIZER, forwardRef, NgModule} from '@angular/core'; import {FormsModule} from '@angular/forms'; -import { forwardRef } from '@angular/core'; import {AppComponent} from './app.component'; import {UpgradeAdapter} from '@angular/upgrade'; import {UpgradeModule} from '@angular/upgrade/static'; -import { SdcUiComponentsModule, SdcUiComponents } from 'onap-ui-angular'; +import {SdcUiComponentsModule} from 'onap-ui-angular'; import {PropertiesAssignmentModule} from './pages/properties-assignment/properties-assignment.module'; import { - DataTypesServiceProvider, CookieServiceProvider, StateServiceFactory, - StateParamsServiceFactory, ScopeServiceFactory, - NotificationServiceProvider, ComponentFactoryProvider + ComponentFactoryProvider, + CookieServiceProvider, + DataTypesServiceProvider, + ModalsHandlerProvider, + NotificationServiceProvider, + ScopeServiceFactory, + StateParamsServiceFactory, + StateServiceFactory } from './utils/ng1-upgraded-provider'; import {ConfigService} from './services/config.service'; import {AuthenticationService} from './services/authentication.service'; @@ -45,7 +49,9 @@ import {UiElementsModule} from './components/ui/ui-elements.module'; import {ConnectionWizardModule} from './pages/composition/graph/connection-wizard/connection-wizard.module'; import {InterfaceOperationModule} from './pages/interface-operation/interface-operation.module'; import {OperationCreatorModule} from './pages/interface-operation/operation-creator/operation-creator.module'; -import {OperationCreatorInterfaceDefinitionModule} from './pages/interface-definition/operation-creator/operation-creator-interface-definition.module'; +import { + OperationCreatorInterfaceDefinitionModule +} from './pages/interface-definition/operation-creator/operation-creator-interface-definition.module'; import {LayoutModule} from './components/layout/layout.module'; import {UserService} from './services/user.service'; import {DynamicComponentService} from './services/dynamic-component.service'; @@ -56,13 +62,12 @@ import {TranslationServiceConfig} from './config/translation.service.config'; import {MultilineEllipsisModule} from './shared/multiline-ellipsis/multiline-ellipsis.module'; import {ServicePathCreatorModule} from './pages/composition/graph/service-path-creator/service-path-creator.module'; import {ServicePathsListModule} from './pages/composition/graph/service-paths-list/service-paths-list.module'; -import { ServicePathSelectorModule } from 'app/ng2/pages/composition/graph/service-path-selector/service-path-selector.module'; -import { CompositionPanelModule } from 'app/ng2/pages/composition/panel/composition-panel.module'; +import {ServicePathSelectorModule} from 'app/ng2/pages/composition/graph/service-path-selector/service-path-selector.module'; +import {CompositionPanelModule} from 'app/ng2/pages/composition/panel/composition-panel.module'; import {CatalogModule} from './pages/catalog/catalog.module'; import {HomeModule} from './pages/home/home.module'; import {WindowRef} from './services/window.service'; import {CatalogService} from './services/catalog.service'; -import { ModalsHandlerProvider } from './utils/ng1-upgraded-provider'; import {PluginFrameModule} from './components/ui/plugin/plugin-frame.module'; import {PluginsService} from './services/plugins.service'; import {EventBusService} from './services/event-bus.service'; @@ -72,7 +77,7 @@ import {AutomatedUpgradeService} from './pages/automated-upgrade/automated-upgra import {AutomatedUpgradeModule} from './pages/automated-upgrade/automated-upgrade.module'; import {WorkspaceModule} from './pages/workspace/workspace.module'; import {ModalsModule} from './components/modals/modals.module'; -import { SharingService, CacheService, HomeService } from 'app/services-ng2'; +import {CacheService, HomeService, SharingService} from 'app/services-ng2'; import {ArtifactConfigService} from "./services/artifact-config.service"; import {IUserProperties} from 'app/models'; import {PluginsModule} from './pages/plugins/plugins-module'; @@ -94,14 +99,13 @@ import {ServiceDependenciesModule} from './components/logic/service-dependencies import {ServiceDependenciesEditorModule} from './pages/service-dependencies-editor/service-dependencies-editor.module'; import {PropertyCreatorModule} from './pages/properties-assignment/property-creator/property-creator.module'; import {DeclareListModule} from './pages/properties-assignment/declare-list/declare-list.module'; -import { ToscaFunctionModule } from "./pages/properties-assignment/tosca-function/tosca-function.module"; +import {ToscaFunctionModule} from "./pages/properties-assignment/tosca-function/tosca-function.module"; import {WorkflowServiceNg2} from './services/workflow.service'; import {ToscaTypesServiceNg2} from "./services/tosca-types.service"; -import {CapabilitiesFilterPropertiesEditorComponentModule} from "./pages/composition/capabilities-filter-properties-editor/capabilities-filter-properties-editor.module"; import {InterfaceOperationHandlerModule} from "./pages/composition/interface-operatons/operation-creator/interface-operation-handler.module"; import {AttributesOutputsModule} from "./pages/attributes-outputs/attributes-outputs.module"; -import { ElementService } from "./services/element.service"; -import { ModelService } from "./services/model.service"; +import {ElementService} from "./services/element.service"; +import {ModelService} from "./services/model.service"; import {ToscaArtifactService} from "./services/tosca-artifact.service"; import {InterfaceDefinitionModule} from "./pages/interface-definition/interface-definition.module"; @@ -167,7 +171,6 @@ export function configServiceFactory(config: ConfigService, authService: Authent ServiceConsumptionCreatorModule, ServiceDependenciesModule, ServiceDependenciesEditorModule, - CapabilitiesFilterPropertiesEditorComponentModule, WorkspaceModule, ModalsModule, CatalogModule, diff --git a/catalog-ui/src/app/ng2/components/logic/service-dependencies/service-dependencies.component.ts b/catalog-ui/src/app/ng2/components/logic/service-dependencies/service-dependencies.component.ts index 04c7a3a03b..50ea60e4ea 100644 --- a/catalog-ui/src/app/ng2/components/logic/service-dependencies/service-dependencies.component.ts +++ b/catalog-ui/src/app/ng2/components/logic/service-dependencies/service-dependencies.component.ts @@ -1,5 +1,6 @@ -/*! +/* * Copyright © 2016-2018 European Support Limited + * Modification Copyright (C) 2022 Nordix Foundation. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -13,25 +14,22 @@ * or implied. See the License for the specific language governing * permissions and limitations under the License. */ + import {Component, ComponentRef, EventEmitter, Input, OnChanges, OnInit, Output} from '@angular/core'; import {ButtonModel, ComponentInstance, InputBEModel, ModalModel, PropertyBEModel, PropertyModel,} from 'app/models'; import {ModalComponent} from 'app/ng2/components/ui/modal/modal.component'; -import {ServiceDependenciesEditorComponent} from 'app/ng2/pages/service-dependencies-editor/service-dependencies-editor.component'; +import {FilterType, ServiceDependenciesEditorComponent} from 'app/ng2/pages/service-dependencies-editor/service-dependencies-editor.component'; import {ModalService} from 'app/ng2/services/modal.service'; import {ComponentGenericResponse} from 'app/ng2/services/responses/component-generic-response'; import {TranslateService} from 'app/ng2/shared/translator/translate.service'; import {ComponentMetadata} from '../../../../models/component-metadata'; import {ServiceInstanceObject} from '../../../../models/service-instance-properties-and-interfaces'; import {TopologyTemplateService} from '../../../services/component-services/topology-template.service'; -import { - CapabilitiesFilterPropertiesEditorComponent -} from "../../../pages/composition/capabilities-filter-properties-editor/capabilities-filter-properties-editor.component"; -import {CapabilityFilterConstraintUI} from "../../../../models/capability-filter-constraint"; import {ToscaFilterConstraintType} from "../../../../models/tosca-filter-constraint-type.enum"; import {CompositionService} from "../../../pages/composition/composition.service"; import {FilterConstraint} from "app/models/filter-constraint"; -import {ConstraintObjectUI} from "../../../../models/ui-models/constraint-object-ui"; -import {FilterConstraintHelper, OPERATOR_TYPES} from "../../../../utils/filter-constraint-helper"; +import {PropertyFilterConstraintUi} from "../../../../models/ui-models/property-filter-constraint-ui"; +import {ConstraintOperatorType, FilterConstraintHelper} from "../../../../utils/filter-constraint-helper"; export enum SourceType { STATIC = 'static', @@ -93,7 +91,7 @@ export class ServiceDependenciesComponent implements OnInit, OnChanges { parentServiceProperties: PropertyBEModel[] = []; constraintProperties: FilterConstraint[] = []; constraintPropertyLabels: string[] = []; - constraintCapabilities: CapabilityFilterConstraintUI[] = []; + constraintCapabilities: PropertyFilterConstraintUi[] = []; constraintCapabilityLabels: string[] = []; operatorTypes: any[]; capabilities: string = ToscaFilterConstraintType.CAPABILITIES; @@ -110,7 +108,7 @@ export class ServiceDependenciesComponent implements OnInit, OnChanges { @Input() componentInstanceCapabilitiesMap: Map; @Output() updateRulesListEvent: EventEmitter = new EventEmitter(); @Output() updateNodeFilterProperties: EventEmitter = new EventEmitter(); - @Output() updateNodeFilterCapabilities: EventEmitter = new EventEmitter(); + @Output() updateNodeFilterCapabilities: EventEmitter = new EventEmitter(); @Output() loadRulesListEvent:EventEmitter = new EventEmitter(); @Output() dependencyStatus = new EventEmitter(); @@ -123,11 +121,11 @@ export class ServiceDependenciesComponent implements OnInit, OnChanges { ngOnInit(): void { this.isLoading = false; this.operatorTypes = [ - {label: FilterConstraintHelper.convertToSymbol(OPERATOR_TYPES.GREATER_THAN), value: OPERATOR_TYPES.GREATER_THAN}, - {label: FilterConstraintHelper.convertToSymbol(OPERATOR_TYPES.LESS_THAN), value: OPERATOR_TYPES.LESS_THAN}, - {label: FilterConstraintHelper.convertToSymbol(OPERATOR_TYPES.EQUAL), value: OPERATOR_TYPES.EQUAL}, - {label: FilterConstraintHelper.convertToSymbol(OPERATOR_TYPES.GREATER_OR_EQUAL), value: OPERATOR_TYPES.GREATER_OR_EQUAL}, - {label: FilterConstraintHelper.convertToSymbol(OPERATOR_TYPES.LESS_OR_EQUAL), value: OPERATOR_TYPES.LESS_OR_EQUAL} + {label: FilterConstraintHelper.convertToSymbol(ConstraintOperatorType.GREATER_THAN), value: ConstraintOperatorType.GREATER_THAN}, + {label: FilterConstraintHelper.convertToSymbol(ConstraintOperatorType.LESS_THAN), value: ConstraintOperatorType.LESS_THAN}, + {label: FilterConstraintHelper.convertToSymbol(ConstraintOperatorType.EQUAL), value: ConstraintOperatorType.EQUAL}, + {label: FilterConstraintHelper.convertToSymbol(ConstraintOperatorType.GREATER_OR_EQUAL), value: ConstraintOperatorType.GREATER_OR_EQUAL}, + {label: FilterConstraintHelper.convertToSymbol(ConstraintOperatorType.LESS_OR_EQUAL), value: ConstraintOperatorType.LESS_OR_EQUAL} ]; this.topologyTemplateService.getComponentInputsWithProperties(this.compositeService.componentType, this.compositeService.uniqueId) .subscribe((result: ComponentGenericResponse) => { @@ -250,17 +248,17 @@ export class ServiceDependenciesComponent implements OnInit, OnChanges { const saveButton: ButtonModel = new ButtonModel(I18nTexts.modalCreate, 'blue', () => this.createNodeFilter(this.properties), this.getDisabled); const modalModel: ModalModel = new ModalModel('l', I18nTexts.addNodeFilterTxt, '', [saveButton, cancelButton], 'standard'); this.modalInstance = this.modalServiceNg2.createCustomModal(modalModel); - this.modalServiceNg2.addDynamicContentToModal( + this.modalServiceNg2.addDynamicContentToModalAndBindInputs( this.modalInstance, ServiceDependenciesEditorComponent, { - currentServiceName: this.currentServiceInstance.name, - operatorTypes: this.operatorTypes, - compositeServiceName: this.compositeService.name, - parentServiceInputs: this.parentServiceInputs, - parentServiceProperties: this.parentServiceProperties, - selectedInstanceProperties: this.selectedInstanceProperties, - selectedInstanceSiblings: this.selectedInstanceSiblings + 'currentServiceName': this.currentServiceInstance.name, + 'operatorTypes': this.operatorTypes, + 'compositeServiceName': this.compositeService.name, + 'parentServiceInputs': this.parentServiceInputs, + 'parentServiceProperties': this.parentServiceProperties, + 'selectedInstanceProperties': this.selectedInstanceProperties, + 'filterType': FilterType.PROPERTY, } ); this.modalInstance.instance.open(); @@ -275,17 +273,18 @@ export class ServiceDependenciesComponent implements OnInit, OnChanges { const saveButton: ButtonModel = new ButtonModel(I18nTexts.modalCreate, 'blue', () => this.createNodeFilterCapabilities(this.capabilities), this.getDisabled); const modalModel: ModalModel = new ModalModel('l', I18nTexts.addNodeFilterTxt, '', [saveButton, cancelButton], 'standard'); this.modalInstance = this.modalServiceNg2.createCustomModal(modalModel); - this.modalServiceNg2.addDynamicContentToModal( + this.modalServiceNg2.addDynamicContentToModalAndBindInputs( this.modalInstance, - CapabilitiesFilterPropertiesEditorComponent, + ServiceDependenciesEditorComponent, { - currentServiceName: this.currentServiceInstance.name, - operatorTypes: this.operatorTypes, - compositeServiceName: this.compositeService.name, - parentServiceInputs: this.parentServiceInputs, - selectedInstanceProperties: this.selectedInstanceProperties, - selectedInstanceSiblings: this.selectedInstanceSiblings, - componentInstanceCapabilitiesMap: this.componentInstanceCapabilitiesMap + 'currentServiceName': this.currentServiceInstance.name, + 'operatorTypes': this.operatorTypes, + 'compositeServiceName': this.compositeService.name, + 'parentServiceInputs': this.parentServiceInputs, + 'parentServiceProperties': this.parentServiceProperties, + 'selectedInstanceProperties': this.selectedInstanceProperties, + 'capabilityNameAndPropertiesMap': this.componentInstanceCapabilitiesMap, + 'filterType': FilterType.CAPABILITY, } ); this.modalInstance.instance.open(); @@ -314,7 +313,7 @@ export class ServiceDependenciesComponent implements OnInit, OnChanges { this.topologyTemplateService.createServiceFilterCapabilitiesConstraints( this.compositeService.uniqueId, this.currentServiceInstance.uniqueId, - new CapabilityFilterConstraintUI(this.modalInstance.instance.dynamicContent.instance.currentRule), + new PropertyFilterConstraintUi(this.modalInstance.instance.dynamicContent.instance.currentRule), this.compositeService.componentType, constraintType ).subscribe( (response) => { @@ -331,20 +330,20 @@ export class ServiceDependenciesComponent implements OnInit, OnChanges { const saveButton: ButtonModel = new ButtonModel(I18nTexts.modalSave, 'blue', () => this.updateNodeFilterCapability(constraintType, index), this.getDisabled); const modalModel: ModalModel = new ModalModel('l', I18nTexts.updateNodeFilterTxt, '', [saveButton, cancelButton], 'standard'); this.modalInstance = this.modalServiceNg2.createCustomModal(modalModel); - - this.modalServiceNg2.addDynamicContentToModal( + const selectedFilterConstraint = new PropertyFilterConstraintUi(this.constraintCapabilities[index]); + this.modalServiceNg2.addDynamicContentToModalAndBindInputs( this.modalInstance, - CapabilitiesFilterPropertiesEditorComponent, + ServiceDependenciesEditorComponent, { - serviceRuleIndex: index, - serviceRules: _.map(this.constraintCapabilities, (rule) => new CapabilityFilterConstraintUI(rule)), - currentServiceName: this.currentServiceInstance.name, - operatorTypes: this.operatorTypes, - compositeServiceName: this.compositeService.name, - parentServiceInputs: this.parentServiceInputs, - selectedInstanceProperties: this.selectedInstanceProperties, - selectedInstanceSiblings: this.selectedInstanceSiblings, - componentInstanceCapabilitiesMap: this.componentInstanceCapabilitiesMap + 'filterConstraint': selectedFilterConstraint, + 'currentServiceName': this.currentServiceInstance.name, + 'operatorTypes': this.operatorTypes, + 'compositeServiceName': this.compositeService.name, + 'parentServiceInputs': this.parentServiceInputs, + 'parentServiceProperties': this.parentServiceProperties, + 'selectedInstanceProperties': this.selectedInstanceProperties, + 'capabilityNameAndPropertiesMap': this.componentInstanceCapabilitiesMap, + 'filterType': FilterType.CAPABILITY, } ); this.modalInstance.instance.open(); @@ -355,19 +354,19 @@ export class ServiceDependenciesComponent implements OnInit, OnChanges { const saveButton: ButtonModel = new ButtonModel(I18nTexts.modalSave, 'blue', () => this.updateNodeFilter(constraintType, index), this.getDisabled); const modalModel: ModalModel = new ModalModel('l', I18nTexts.updateNodeFilterTxt, '', [saveButton, cancelButton], 'standard'); this.modalInstance = this.modalServiceNg2.createCustomModal(modalModel); - this.modalServiceNg2.addDynamicContentToModal( + const selectedFilterConstraint = new PropertyFilterConstraintUi(this.constraintProperties[index]); + this.modalServiceNg2.addDynamicContentToModalAndBindInputs( this.modalInstance, ServiceDependenciesEditorComponent, { - serviceRuleIndex: index, - serviceRules: this.constraintProperties.map(rule => new ConstraintObjectUI(rule)), - currentServiceName: this.currentServiceInstance.name, - operatorTypes: this.operatorTypes, - compositeServiceName: this.compositeService.name, - parentServiceInputs: this.parentServiceInputs, - parentServiceProperties: this.parentServiceProperties, - selectedInstanceProperties: this.selectedInstanceProperties, - selectedInstanceSiblings: this.selectedInstanceSiblings + 'filterConstraint': selectedFilterConstraint, + 'currentServiceName': this.currentServiceInstance.name, + 'operatorTypes': this.operatorTypes, + 'compositeServiceName': this.compositeService.name, + 'parentServiceInputs': this.parentServiceInputs, + 'parentServiceProperties': this.parentServiceProperties, + 'selectedInstanceProperties': this.selectedInstanceProperties, + 'filterType': FilterType.PROPERTY } ); this.modalInstance.instance.open(); @@ -400,7 +399,7 @@ export class ServiceDependenciesComponent implements OnInit, OnChanges { this.topologyTemplateService.updateServiceFilterCapabilitiesConstraint( this.compositeService.uniqueId, this.currentServiceInstance.uniqueId, - new CapabilityFilterConstraintUI(this.modalInstance.instance.dynamicContent.instance.currentRule), + new PropertyFilterConstraintUi(this.modalInstance.instance.dynamicContent.instance.currentRule), this.compositeService.componentType, constraintType, index 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 53563e07a2..c1743e56c3 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 @@ -20,15 +20,15 @@ import {Component, ComponentRef, EventEmitter, Input, OnChanges, OnInit, Output} from '@angular/core'; import {ButtonModel, ComponentInstance, InputBEModel, ModalModel, PropertyBEModel,} from 'app/models'; import {ModalComponent} from 'app/ng2/components/ui/modal/modal.component'; -import {ServiceDependenciesEditorComponent} from 'app/ng2/pages/service-dependencies-editor/service-dependencies-editor.component'; +import {FilterType, ServiceDependenciesEditorComponent} from 'app/ng2/pages/service-dependencies-editor/service-dependencies-editor.component'; import {ModalService} from 'app/ng2/services/modal.service'; import {TranslateService} from 'app/ng2/shared/translator/translate.service'; import {ComponentMetadata} from '../../../../models/component-metadata'; import {TopologyTemplateService} from '../../../services/component-services/topology-template.service'; import {ToscaFilterConstraintType} from "../../../../models/tosca-filter-constraint-type.enum"; import {FilterConstraint} from "app/models/filter-constraint"; -import {ConstraintObjectUI} from "../../../../models/ui-models/constraint-object-ui"; -import {FilterConstraintHelper, OPERATOR_TYPES} from "../../../../utils/filter-constraint-helper"; +import {PropertyFilterConstraintUi} from "../../../../models/ui-models/property-filter-constraint-ui"; +import {FilterConstraintHelper, ConstraintOperatorType} from "../../../../utils/filter-constraint-helper"; class I18nTexts { static addSubstitutionFilterTxt: string; @@ -86,11 +86,11 @@ export class SubstitutionFilterComponent implements OnInit, OnChanges { ngOnInit(): void { this.isLoading = false; this.operatorTypes = [ - {label: FilterConstraintHelper.convertToSymbol(OPERATOR_TYPES.GREATER_THAN), value: OPERATOR_TYPES.GREATER_THAN}, - {label: FilterConstraintHelper.convertToSymbol(OPERATOR_TYPES.LESS_THAN), value: OPERATOR_TYPES.LESS_THAN}, - {label: FilterConstraintHelper.convertToSymbol(OPERATOR_TYPES.EQUAL), value: OPERATOR_TYPES.EQUAL}, - {label: FilterConstraintHelper.convertToSymbol(OPERATOR_TYPES.GREATER_OR_EQUAL), value: OPERATOR_TYPES.GREATER_OR_EQUAL}, - {label: FilterConstraintHelper.convertToSymbol(OPERATOR_TYPES.LESS_OR_EQUAL), value: OPERATOR_TYPES.LESS_OR_EQUAL} + {label: FilterConstraintHelper.convertToSymbol(ConstraintOperatorType.GREATER_THAN), value: ConstraintOperatorType.GREATER_THAN}, + {label: FilterConstraintHelper.convertToSymbol(ConstraintOperatorType.LESS_THAN), value: ConstraintOperatorType.LESS_THAN}, + {label: FilterConstraintHelper.convertToSymbol(ConstraintOperatorType.EQUAL), value: ConstraintOperatorType.EQUAL}, + {label: FilterConstraintHelper.convertToSymbol(ConstraintOperatorType.GREATER_OR_EQUAL), value: ConstraintOperatorType.GREATER_OR_EQUAL}, + {label: FilterConstraintHelper.convertToSymbol(ConstraintOperatorType.LESS_OR_EQUAL), value: ConstraintOperatorType.LESS_OR_EQUAL} ]; this.loadSubstitutionFilter(); this.translateService.languageChangedObservable.subscribe((lang) => { @@ -123,16 +123,17 @@ export class SubstitutionFilterComponent implements OnInit, OnChanges { 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( + this.modalServiceNg2.addDynamicContentToModalAndBindInputs( this.modalInstance, ServiceDependenciesEditorComponent, { - currentServiceName: this.currentServiceInstance.name, - operatorTypes: this.operatorTypes, - compositeServiceName: this.compositeService.name, - parentServiceInputs: this.parentServiceInputs, - parentServiceProperties: this.parentServiceProperties, - selectedInstanceProperties: this.parentServiceProperties, + 'currentServiceName': this.currentServiceInstance.name, + 'operatorTypes': this.operatorTypes, + 'compositeServiceName': this.compositeService.name, + 'parentServiceInputs': this.parentServiceInputs, + 'parentServiceProperties': this.parentServiceProperties, + 'selectedInstanceProperties': this.selectedInstanceProperties, + 'filterType': FilterType.PROPERTY } ); this.modalInstance.instance.open(); @@ -161,18 +162,19 @@ export class SubstitutionFilterComponent implements OnInit, OnChanges { const updateButton: ButtonModel = new ButtonModel(I18nTexts.modalSave, 'blue', () => this.updateSubstitutionFilter(constraintType, index), this.getDisabled); const modalModel: ModalModel = new ModalModel('l', I18nTexts.updateSubstitutionFilterTxt, '', [updateButton, cancelButton], 'standard'); this.modalInstance = this.modalServiceNg2.createCustomModal(modalModel); - this.modalServiceNg2.addDynamicContentToModal( + const selectedFilterConstraint = new PropertyFilterConstraintUi(this.constraintProperties[index]); + this.modalServiceNg2.addDynamicContentToModalAndBindInputs( this.modalInstance, ServiceDependenciesEditorComponent, { - serviceRuleIndex: index, - serviceRules: _.map(this.constraintProperties, (constraint) => new ConstraintObjectUI(constraint)), - currentServiceName: this.currentServiceInstance.name, - operatorTypes: this.operatorTypes, - compositeServiceName: this.compositeService.name, - parentServiceInputs: this.parentServiceInputs, - parentServiceProperties: this.parentServiceProperties, - selectedInstanceProperties: this.parentServiceProperties, + 'filterConstraint': selectedFilterConstraint, + 'currentServiceName': this.currentServiceInstance.name, + 'operatorTypes': this.operatorTypes, + 'compositeServiceName': this.compositeService.name, + 'parentServiceInputs': this.parentServiceInputs, + 'parentServiceProperties': this.parentServiceProperties, + 'selectedInstanceProperties': this.selectedInstanceProperties, + 'filterType': FilterType.PROPERTY } ); this.modalInstance.instance.open(); diff --git a/catalog-ui/src/app/ng2/components/ui/form-components/dropdown/ui-element-dropdown.component.html b/catalog-ui/src/app/ng2/components/ui/form-components/dropdown/ui-element-dropdown.component.html index 9dca01eb61..7095e02f60 100644 --- a/catalog-ui/src/app/ng2/components/ui/form-components/dropdown/ui-element-dropdown.component.html +++ b/catalog-ui/src/app/ng2/components/ui/form-components/dropdown/ui-element-dropdown.component.html @@ -15,5 +15,5 @@ --> diff --git a/catalog-ui/src/app/ng2/pages/composition/capabilities-filter-properties-editor/capabilities-filter-properties-editor.component.html b/catalog-ui/src/app/ng2/pages/composition/capabilities-filter-properties-editor/capabilities-filter-properties-editor.component.html deleted file mode 100644 index 1dcbc16c12..0000000000 --- a/catalog-ui/src/app/ng2/pages/composition/capabilities-filter-properties-editor/capabilities-filter-properties-editor.component.html +++ /dev/null @@ -1,81 +0,0 @@ - - -
-
- -
-
-
- - - -
- -
- - - -
- -
- - -
- -
- - - -
- -
- - - - - -
-
-
-
- -
diff --git a/catalog-ui/src/app/ng2/pages/composition/capabilities-filter-properties-editor/capabilities-filter-properties-editor.component.less b/catalog-ui/src/app/ng2/pages/composition/capabilities-filter-properties-editor/capabilities-filter-properties-editor.component.less deleted file mode 100644 index 188fb7b5ef..0000000000 --- a/catalog-ui/src/app/ng2/pages/composition/capabilities-filter-properties-editor/capabilities-filter-properties-editor.component.less +++ /dev/null @@ -1,44 +0,0 @@ -@import './../../../../../assets/styles/variables.less'; - - -.sdc-modal-top-bar { - display: flex; - justify-content: flex-end; -} - -.i-sdc-form-content { - display: flex; - flex-direction: column; - margin-top: 10px; - padding-bottom: 20px; - - .i-sdc-form-item { - width: 250px; - &.operation { - width: 60px; - } - } - - .rule-builder-content { - display: flex; - align-items: flex-end; - .rule-input-field { - flex: 1; - &:not(:last-of-type) { - margin-right: 20px; - } - &.operator{ - width: 55px; - flex: 0 1 auto; - } - &.assigned-value-field { - margin-bottom: 10px; - } - /deep/ ui-element-dropdown select, - /deep/ ui-element-input input { - height: 30px; - } - } - - } -} diff --git a/catalog-ui/src/app/ng2/pages/composition/capabilities-filter-properties-editor/capabilities-filter-properties-editor.component.ts b/catalog-ui/src/app/ng2/pages/composition/capabilities-filter-properties-editor/capabilities-filter-properties-editor.component.ts deleted file mode 100644 index b59591bd06..0000000000 --- a/catalog-ui/src/app/ng2/pages/composition/capabilities-filter-properties-editor/capabilities-filter-properties-editor.component.ts +++ /dev/null @@ -1,218 +0,0 @@ -/* -* ============LICENSE_START======================================================= -* SDC -* ================================================================================ -* Copyright (C) 2020 Nordix Foundation. All rights reserved. -* ================================================================================ -* Licensed under the Apache License, Version 2.0 (the "License"); -* you may not use this file except in compliance with the License. -* You may obtain a copy of the License at -* -* http://www.apache.org/licenses/LICENSE-2.0 -* Unless required by applicable law or agreed to in writing, software -* distributed under the License is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* See the License for the specific language governing permissions and -* limitations under the License. -* -* SPDX-License-Identifier: Apache-2.0 -* ============LICENSE_END========================================================= -*/ - -import {Component} from '@angular/core'; -import {InputBEModel, PropertyBEModel, PropertyModel} from 'app/models'; -import {DropdownValue} from 'app/ng2/components/ui/form-components/dropdown/ui-element-dropdown.component'; -import {ServiceServiceNg2} from 'app/ng2/services/component-services/service.service'; -import {PROPERTY_DATA} from 'app/utils'; -import {ServiceInstanceObject} from '../../../../models/service-instance-properties-and-interfaces'; -import {CapabilityFilterConstraintUI} from "../../../../models/capability-filter-constraint"; -import {OPERATOR_TYPES} from "../../../../utils/filter-constraint-helper"; - -export class UIDropDownSourceTypesElement extends DropdownValue { - options: any[]; - assignedLabel: string; - type: string; - - constructor(input?: any) { - super(input ? input.value || '' : "", input ? input.label || '' : ""); - if (input) { - this.options = input.options; - this.assignedLabel = input.assignedLabel; - this.type = input.type; - } - } -} - -@Component({ - selector: 'app-capabilities-filter-properties-editor', - templateUrl: './capabilities-filter-properties-editor.component.html', - styleUrls: ['./capabilities-filter-properties-editor.component.less'], - providers: [ServiceServiceNg2] -}) -export class CapabilitiesFilterPropertiesEditorComponent { - - input: { - serviceRuleIndex: number, - serviceRules: CapabilityFilterConstraintUI[], - compositeServiceName: string, - currentServiceName: string, - parentServiceInputs: InputBEModel[], - selectedInstanceProperties: PropertyBEModel[], - operatorTypes: DropdownValue[], - selectedInstanceSiblings: ServiceInstanceObject[], - componentInstanceCapabilitiesMap: Map, - }; - currentServiceName: string; - selectedServiceProperties: PropertyBEModel[]; - operatorTypes: DropdownValue[]; - sourceTypes: UIDropDownSourceTypesElement[] = []; - currentRule: CapabilityFilterConstraintUI; - currentIndex: number; - listOfValuesToAssign: DropdownValue[]; - listOfSourceOptions: PropertyBEModel[]; - assignedValueLabel: string; - serviceRulesList: CapabilityFilterConstraintUI[]; - - capabilitiesNames: string[]; - selectedPropertiesByCapabilityName: Array; - selectedCapabilityName: string; - capabilityProperties: DropdownValue[]; - - selectedCapabilitiesPropertyObject: PropertyBEModel; - - SOURCE_TYPES = { - STATIC: {label: 'Static', value: 'static'}, - SERVICE_PROPERTY: {label: 'Service Property', value: 'property'}, - CAPABILITY_NAME: {label: 'Name', value: 'name'} - }; - - ngOnInit() { - this.capabilitiesNames = Array.from(this.input.componentInstanceCapabilitiesMap.keys()); - this.currentIndex = this.input.serviceRuleIndex; - this.serviceRulesList = this.input.serviceRules; - this.currentRule = this.serviceRulesList && this.input.serviceRuleIndex >= 0 ? - this.serviceRulesList[this.input.serviceRuleIndex] : - new CapabilityFilterConstraintUI({ - capabilityName: this.SOURCE_TYPES.CAPABILITY_NAME.value, - sourceName: this.SOURCE_TYPES.STATIC.value, - sourceType: this.SOURCE_TYPES.STATIC.value, value: '', - constraintOperator: OPERATOR_TYPES.EQUAL - }); - this.currentServiceName = this.input.currentServiceName; - this.operatorTypes = this.input.operatorTypes; - - this.initSourceTypes(); - this.syncRuleData(); - this.updateSourceTypesRelatedValues(); - this.onCapabilityNameChanged(this.currentRule.capabilityName) - } - - initSourceTypes() { - this.sourceTypes.push({ - label: this.SOURCE_TYPES.STATIC.label, - value: this.SOURCE_TYPES.STATIC.value, - options: [], - assignedLabel: this.SOURCE_TYPES.STATIC.label, - type: this.SOURCE_TYPES.STATIC.value - }); - this.sourceTypes.push({ - label: this.input.compositeServiceName, - value: this.input.compositeServiceName, - assignedLabel: this.SOURCE_TYPES.SERVICE_PROPERTY.label, - type: this.SOURCE_TYPES.SERVICE_PROPERTY.value, - options: this.input.parentServiceInputs - }); - _.forEach(this.input.selectedInstanceSiblings, (sib) => - this.sourceTypes.push({ - label: sib.name, - value: sib.name, - options: sib.properties || [], - assignedLabel: this.SOURCE_TYPES.SERVICE_PROPERTY.label, - type: this.SOURCE_TYPES.SERVICE_PROPERTY.value - }) - ); - } - - syncRuleData() { - if (!this.currentRule.sourceName && this.currentRule.sourceType === this.SOURCE_TYPES.STATIC.value) { - this.currentRule.sourceName = this.SOURCE_TYPES.STATIC.value; - } - if (this.input.componentInstanceCapabilitiesMap) { - this.selectedCapabilitiesPropertyObject = Array.from(this.input.componentInstanceCapabilitiesMap - .get(this.currentRule.capabilityName)) - .find(property => property.name == this.currentRule.servicePropertyName); - } - this.updateOperatorTypesList(); - this.updateSourceTypesRelatedValues(); - } - - updateOperatorTypesList() { - if (this.selectedCapabilitiesPropertyObject && PROPERTY_DATA.SIMPLE_TYPES_COMPARABLE.indexOf(this.selectedCapabilitiesPropertyObject.type) === -1) { - this.operatorTypes = [{label: '=', value: OPERATOR_TYPES.EQUAL}]; - this.currentRule.constraintOperator = OPERATOR_TYPES.EQUAL; - } else { - this.operatorTypes = this.input.operatorTypes; - } - } - - updateSourceTypesRelatedValues() { - if (this.currentRule.sourceName) { - const selectedSourceType: UIDropDownSourceTypesElement = this.sourceTypes.find( - (t) => t.value === this.currentRule.sourceName && t.type === this.currentRule.sourceType - ); - if (selectedSourceType) { - this.listOfSourceOptions = selectedSourceType.options || []; - this.assignedValueLabel = selectedSourceType.assignedLabel || this.SOURCE_TYPES.STATIC.label; - this.filterOptionsByType(); - } - } - } - - onCapabilityNameChanged = (value: any): void => { - this.selectedPropertiesByCapabilityName = this.input.componentInstanceCapabilitiesMap.get(value); - this.capabilityProperties = _.map(this.selectedPropertiesByCapabilityName, (prop) => new DropdownValue(prop.name, prop.name)); - this.selectedCapabilityName = value; - this.updateOperatorTypesList(); - this.filterOptionsByType(); - } - - onServicePropertyChanged() { - this.syncRuleData(); - this.filterOptionsByType(); - this.currentRule.value = ''; - } - - onSelectSourceType() { - this.currentRule.sourceType = this.currentRule.sourceName === this.SOURCE_TYPES.STATIC.value ? - this.SOURCE_TYPES.STATIC.value : - this.SOURCE_TYPES.SERVICE_PROPERTY.value; - this.updateSourceTypesRelatedValues(); - this.currentRule.value = ''; - } - - filterOptionsByType() { - if (!this.selectedCapabilitiesPropertyObject) { - this.listOfValuesToAssign = []; - return; - } - this.listOfValuesToAssign = this.listOfSourceOptions.reduce((result, op: PropertyModel) => { - if (op.type === this.selectedCapabilitiesPropertyObject.type && (!op.schemaType || op.schemaType === this.selectedCapabilitiesPropertyObject.schemaType)) { - result.push(new DropdownValue(op.name, op.name)); - } - return result; - }, []); - } - - onValueChange(isValidValue) { - this.currentRule.updateValidity(isValidValue); - } - - checkFormValidForSubmit() { - if (!this.serviceRulesList) { - const isStatic = this.currentRule.sourceName === this.SOURCE_TYPES.STATIC.value; - return this.currentRule.isValidRule(isStatic); - } - return this.serviceRulesList.every((rule) => rule.isValidRule(rule.sourceName === this.SOURCE_TYPES.STATIC.value)); - } - -} diff --git a/catalog-ui/src/app/ng2/pages/composition/capabilities-filter-properties-editor/capabilities-filter-properties-editor.module.ts b/catalog-ui/src/app/ng2/pages/composition/capabilities-filter-properties-editor/capabilities-filter-properties-editor.module.ts deleted file mode 100644 index 27bcb8a4e0..0000000000 --- a/catalog-ui/src/app/ng2/pages/composition/capabilities-filter-properties-editor/capabilities-filter-properties-editor.module.ts +++ /dev/null @@ -1,46 +0,0 @@ -/* -* ============LICENSE_START======================================================= -* SDC -* ================================================================================ -* Copyright (C) 2020 Nordix Foundation. All rights reserved. -* ================================================================================ -* Licensed under the Apache License, Version 2.0 (the "License"); -* you may not use this file except in compliance with the License. -* You may obtain a copy of the License at -* -* http://www.apache.org/licenses/LICENSE-2.0 -* Unless required by applicable law or agreed to in writing, software -* distributed under the License is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* See the License for the specific language governing permissions and -* limitations under the License. -* -* SPDX-License-Identifier: Apache-2.0 -* ============LICENSE_END========================================================= -*/ - -import {CommonModule} from '@angular/common'; -import {NgModule} from '@angular/core'; -import {FormsModule} from '@angular/forms'; -import {FormElementsModule} from 'app/ng2/components/ui/form-components/form-elements.module'; -import {UiElementsModule} from 'app/ng2/components/ui/ui-elements.module'; -import {CapabilitiesFilterPropertiesEditorComponent} from "./capabilities-filter-properties-editor.component"; - -@NgModule({ - declarations: [ - CapabilitiesFilterPropertiesEditorComponent - ], - imports: [ - CommonModule, - FormsModule, - FormElementsModule, - UiElementsModule - ], - exports: [], - entryComponents: [ - CapabilitiesFilterPropertiesEditorComponent - ], - providers: [] -}) -export class CapabilitiesFilterPropertiesEditorComponentModule { -} diff --git a/catalog-ui/src/app/ng2/pages/composition/panel/panel-tabs/service-dependencies-tab/service-dependencies-tab.component.ts b/catalog-ui/src/app/ng2/pages/composition/panel/panel-tabs/service-dependencies-tab/service-dependencies-tab.component.ts index ce1a43dd3b..7ca4604004 100644 --- a/catalog-ui/src/app/ng2/pages/composition/panel/panel-tabs/service-dependencies-tab/service-dependencies-tab.component.ts +++ b/catalog-ui/src/app/ng2/pages/composition/panel/panel-tabs/service-dependencies-tab/service-dependencies-tab.component.ts @@ -1,4 +1,25 @@ -import {Component, Input} from '@angular/core'; +/* + * - + * ============LICENSE_START======================================================= + * Copyright (C) 2022 Nordix Foundation. + * ================================================================================ + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + * SPDX-License-Identifier: Apache-2.0 + * ============LICENSE_END========================================================= + */ + +import {Component, Input, OnInit} from '@angular/core'; import {Store} from '@ngxs/store'; import { CapabilitiesGroup, Capability, @@ -16,7 +37,6 @@ import {ComponentGenericResponse} from '../../../../../services/responses/compon import {WorkspaceService} from '../../../../workspace/workspace.service'; import {SelectedComponentType} from '../../../common/store/graph.actions'; import {CompositionService} from '../../../composition.service'; -import {CapabilityFilterConstraint} from "../../../../../../models/capability-filter-constraint"; import {FilterConstraint} from "../../../../../../models/filter-constraint"; @Component({ @@ -24,7 +44,7 @@ import {FilterConstraint} from "../../../../../../models/filter-constraint"; templateUrl: 'service-dependencies-tab.component.html', styleUrls: ['service-dependencies-tab.component.less'] }) -export class ServiceDependenciesTabComponent { +export class ServiceDependenciesTabComponent implements OnInit { isComponentInstanceSelected: boolean; selectedInstanceSiblings: ServiceInstanceObject[]; @@ -35,7 +55,6 @@ export class ServiceDependenciesTabComponent { componentInstanceCapabilityProperties: CapabilitiesGroup; metaData: ComponentMetadata; componentInstanceCapabilitiesMap : Map = new Map(); - componentInstanceCapabilitiesNames: string[]; @Input() isViewOnly: boolean; @Input() componentType: SelectedComponentType; @@ -49,7 +68,7 @@ export class ServiceDependenciesTabComponent { private eventListenerService: EventListenerService) { } - ngOnInit() { + ngOnInit(): void { this.metaData = this.workspaceService.metadata; this.isComponentInstanceSelected = this.componentType === SelectedComponentType.COMPONENT_INSTANCE; this.initInstancesWithProperties(); @@ -73,7 +92,7 @@ export class ServiceDependenciesTabComponent { this.selectedInstanceConstraints = this.componentInstancesConstraints[this.component.uniqueId].properties; } - public updateSelectedInstanceCapabilitiesConstraints = (constraintsList:Array):void => { + public updateSelectedInstanceCapabilitiesConstraints = (constraintsList:Array):void => { this.componentInstancesConstraints[this.component.uniqueId].capabilities = constraintsList; this.selectedInstanceConstraints = this.componentInstancesConstraints[this.component.uniqueId].capabilities; } @@ -97,7 +116,7 @@ export class ServiceDependenciesTabComponent { } } - private initInstancesWithCapabilityProperties = (): void => { + private initInstancesWithCapabilityProperties(): void { this.componentInstanceCapabilityProperties = this.component.capabilities; this.updateComponentInstanceCapabilities(); } diff --git a/catalog-ui/src/app/ng2/pages/service-dependencies-editor/service-dependencies-editor.component.html b/catalog-ui/src/app/ng2/pages/service-dependencies-editor/service-dependencies-editor.component.html index 4e6993a1e4..922cda6982 100644 --- a/catalog-ui/src/app/ng2/pages/service-dependencies-editor/service-dependencies-editor.component.html +++ b/catalog-ui/src/app/ng2/pages/service-dependencies-editor/service-dependencies-editor.component.html @@ -1,3 +1,25 @@ + +
@@ -5,20 +27,31 @@
+
+ + + +
+ (change)="onPropertyChange()">
-
- +
diff --git a/catalog-ui/src/app/ng2/pages/service-dependencies-editor/service-dependencies-editor.component.ts b/catalog-ui/src/app/ng2/pages/service-dependencies-editor/service-dependencies-editor.component.ts index ba7a4946ca..f8a2160374 100644 --- a/catalog-ui/src/app/ng2/pages/service-dependencies-editor/service-dependencies-editor.component.ts +++ b/catalog-ui/src/app/ng2/pages/service-dependencies-editor/service-dependencies-editor.component.ts @@ -1,5 +1,6 @@ /*! * Copyright © 2016-2018 European Support Limited + * Modification Copyright (C) 2022 Nordix Foundation. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -13,22 +14,20 @@ * or implied. See the License for the specific language governing * permissions and limitations under the License. */ -import {Component, OnInit} from '@angular/core'; -import {InputBEModel, PropertyBEModel, PropertyFEModel} from 'app/models'; +import {Component, Input, OnInit} from '@angular/core'; +import {InputBEModel, PropertyBEModel, PropertyFEModel, PropertyModel} from 'app/models'; import {SourceType} from 'app/ng2/components/logic/service-dependencies/service-dependencies.component'; import {DropdownValue} from 'app/ng2/components/ui/form-components/dropdown/ui-element-dropdown.component'; import {ServiceServiceNg2} from 'app/ng2/services/component-services/service.service'; import {PROPERTY_DATA} from 'app/utils'; -import {ServiceInstanceObject} from '../../../models/service-instance-properties-and-interfaces'; import {PropertiesUtils} from '../properties-assignment/services/properties.utils'; import {ToscaFunctionValidationEvent} from "../properties-assignment/tosca-function/tosca-function.component"; import {InstanceFeDetails} from "../../../models/instance-fe-details"; import {CompositionService} from "../composition/composition.service"; import {ToscaGetFunction} from "../../../models/tosca-get-function"; -import {ToscaFunction} from "../../../models/tosca-function"; -import {ToscaFunctionType} from "../../../models/tosca-function-type.enum"; -import {ConstraintObjectUI} from "../../../models/ui-models/constraint-object-ui"; -import {OPERATOR_TYPES} from "../../../utils/filter-constraint-helper"; +import {PropertyFilterConstraintUi} from "../../../models/ui-models/property-filter-constraint-ui"; +import {ConstraintOperatorType, FilterConstraintHelper} from "../../../utils/filter-constraint-helper"; +import {ToscaFunctionHelper} from "../../../utils/tosca-function-helper"; @Component({ selector: 'service-dependencies-editor', @@ -38,30 +37,42 @@ import {OPERATOR_TYPES} from "../../../utils/filter-constraint-helper"; }) export class ServiceDependenciesEditorComponent implements OnInit { - input: { - serviceRuleIndex: number, - serviceRules: ConstraintObjectUI[], - compositeServiceName: string, - currentServiceName: string, - parentServiceInputs: InputBEModel[], - parentServiceProperties: PropertyBEModel[]; - selectedInstanceProperties: PropertyBEModel[], - operatorTypes: DropdownValue[], - selectedInstanceSiblings: ServiceInstanceObject[] - }; + @Input() serviceRuleIndex: number; + @Input() serviceRules: PropertyFilterConstraintUi[]; + @Input() compositeServiceName: string; + @Input() currentServiceName: string; + @Input() parentServiceInputs: InputBEModel[]; + @Input() parentServiceProperties: PropertyBEModel[]; + @Input() selectedInstanceProperties: PropertyBEModel[]; + @Input() allowedOperators: ConstraintOperatorType[] = [ + ConstraintOperatorType.GREATER_THAN, + ConstraintOperatorType.LESS_THAN, + ConstraintOperatorType.EQUAL, + ConstraintOperatorType.GREATER_OR_EQUAL, + ConstraintOperatorType.LESS_OR_EQUAL + ]; + @Input() capabilityNameAndPropertiesMap: Map; + @Input() filterType: FilterType; + @Input() filterConstraint: PropertyFilterConstraintUi; //output - currentRule: ConstraintObjectUI; - - currentServiceName: string; - selectedServiceProperties: PropertyBEModel[] = []; - ddValueSelectedServicePropertiesNames: DropdownValue[]; - operatorTypes: DropdownValue[]; - currentIndex: number; - serviceRulesList: ConstraintObjectUI[]; + currentRule: PropertyFilterConstraintUi; + + FILTER_TYPE_CAPABILITY: FilterType = FilterType.CAPABILITY + + operatorTypes: DropdownValue[] = [ + {label: FilterConstraintHelper.convertToSymbol(ConstraintOperatorType.GREATER_THAN), value: ConstraintOperatorType.GREATER_THAN}, + {label: FilterConstraintHelper.convertToSymbol(ConstraintOperatorType.LESS_THAN), value: ConstraintOperatorType.LESS_THAN}, + {label: FilterConstraintHelper.convertToSymbol(ConstraintOperatorType.EQUAL), value: ConstraintOperatorType.EQUAL}, + {label: FilterConstraintHelper.convertToSymbol(ConstraintOperatorType.GREATER_OR_EQUAL), value: ConstraintOperatorType.GREATER_OR_EQUAL}, + {label: FilterConstraintHelper.convertToSymbol(ConstraintOperatorType.LESS_OR_EQUAL), value: ConstraintOperatorType.LESS_OR_EQUAL} + ]; + + servicePropertyDropdownList: DropdownValue[]; isLoading: false; selectedProperty: PropertyFEModel; selectedSourceType: string; componentInstanceMap: Map = new Map(); + capabilityDropdownList: DropdownValue[] = []; SOURCE_TYPES = { STATIC: {label: 'Static', value: SourceType.STATIC}, @@ -71,13 +82,6 @@ export class ServiceDependenciesEditorComponent implements OnInit { constructor(private propertiesUtils: PropertiesUtils, private compositionService: CompositionService) {} ngOnInit(): void { - this.currentIndex = this.input.serviceRuleIndex; - this.serviceRulesList = this.input.serviceRules; - if (this.input.selectedInstanceProperties) { - this.selectedServiceProperties = this.input.selectedInstanceProperties; - } - this.currentServiceName = this.input.currentServiceName; - this.operatorTypes = this.input.operatorTypes; if (this.compositionService.componentInstances) { this.compositionService.componentInstances.forEach(value => { this.componentInstanceMap.set(value.uniqueId, { @@ -85,15 +89,59 @@ export class ServiceDependenciesEditorComponent implements OnInit { }); }); } + this.initCapabilityDropdown(); this.initCurrentRule(); + this.initConstraintOperatorOptions(); this.initSelectedSourceType(); - this.selectedProperty = new PropertyFEModel(this.selectedServiceProperties.find(property => property.name === this.currentRule.servicePropertyName)); - this.selectedProperty.toscaFunction = undefined; - this.selectedProperty.value = undefined; - this.ddValueSelectedServicePropertiesNames = _.map(this.input.selectedInstanceProperties, (prop) => new DropdownValue(prop.name, prop.name)); + this.initPropertyDropdown(); this.syncRuleData(); - if (this.isValueToscaFunction(this.currentRule.value)) { - this.selectedProperty.toscaFunction = this.currentRule.value; + } + + + private initCapabilityDropdown(): void { + if (this.filterType == FilterType.CAPABILITY) { + this.capabilityDropdownList = [ + new DropdownValue(undefined, 'Select'), + ...Array.from(this.capabilityNameAndPropertiesMap.keys()).map(capabilityName => new DropdownValue(capabilityName, capabilityName)) + ]; + } + } + + private initPropertyDropdown(): void { + let propertyList: PropertyBEModel[] = []; + if (this.filterType == FilterType.CAPABILITY) { + if (this.currentRule.capabilityName) { + propertyList = this.capabilityNameAndPropertiesMap.get(this.currentRule.capabilityName); + } + } else { + propertyList = this.selectedInstanceProperties; + } + let selectLabel; + if (this.filterType == FilterType.CAPABILITY) { + selectLabel = this.currentRule.capabilityName ? 'Select' : 'Select a Capability'; + } else { + selectLabel = 'Select'; + } + this.servicePropertyDropdownList = [new DropdownValue(undefined, selectLabel), ...propertyList.map(prop => new DropdownValue(prop.name, prop.name))]; + } + + private initConstraintOperatorOptions(): void { + if (!this.selectedProperty) { + this.operatorTypes = [new DropdownValue(undefined, 'Select a Property')]; + return; + } + + if (PROPERTY_DATA.SIMPLE_TYPES_COMPARABLE.indexOf(this.selectedProperty.type) === -1) { + if (this.currentRule.constraintOperator !== ConstraintOperatorType.EQUAL) { + this.currentRule.constraintOperator = ConstraintOperatorType.EQUAL; + } + this.operatorTypes = [new DropdownValue(ConstraintOperatorType.EQUAL, FilterConstraintHelper.convertToSymbol(ConstraintOperatorType.EQUAL))]; + } else { + const operatorList: DropdownValue[] = []; + this.allowedOperators.forEach(constraintOperatorType => + operatorList.push(new DropdownValue(constraintOperatorType, FilterConstraintHelper.convertToSymbol(constraintOperatorType))) + ); + this.operatorTypes = operatorList; } } @@ -106,24 +154,29 @@ export class ServiceDependenciesEditorComponent implements OnInit { } private initCurrentRule(): void { - if (this.serviceRulesList && this.input.serviceRuleIndex >= 0) { - this.currentRule = new ConstraintObjectUI(this.serviceRulesList[this.input.serviceRuleIndex]); + if (this.filterConstraint) { + this.currentRule = new PropertyFilterConstraintUi(this.filterConstraint); } else { - this.currentRule = new ConstraintObjectUI({ + this.currentRule = new PropertyFilterConstraintUi({ sourceName: SourceType.STATIC, sourceType: SourceType.STATIC, - value: '', - constraintOperator: OPERATOR_TYPES.EQUAL + constraintOperator: ConstraintOperatorType.EQUAL, + value: undefined }); } } - onServicePropertyChanged(): void { + onCapabilityChange(): void { + this.initPropertyDropdown(); + this.resetSelectedProperty(); + } + + onPropertyChange(): void { this.currentRule.sourceName = undefined; this.currentRule.value = undefined; - this.selectedProperty = undefined; + this.onValueChange(false); this.updateSelectedProperty(); - this.updateOperatorTypesList(); + this.initConstraintOperatorOptions(); } syncRuleData(): void { @@ -132,16 +185,7 @@ export class ServiceDependenciesEditorComponent implements OnInit { this.currentRule.sourceType = SourceType.STATIC; } this.initSelectedProperty(); - this.updateOperatorTypesList(); - } - - updateOperatorTypesList(): void { - if (this.selectedProperty && PROPERTY_DATA.SIMPLE_TYPES_COMPARABLE.indexOf(this.selectedProperty.type) === -1) { - this.operatorTypes = [{label: '=', value: OPERATOR_TYPES.EQUAL}]; - this.currentRule.constraintOperator = OPERATOR_TYPES.EQUAL; - } else { - this.operatorTypes = this.input.operatorTypes; - } + this.initConstraintOperatorOptions(); } onValueChange(isValidValue:any): void { @@ -157,19 +201,27 @@ export class ServiceDependenciesEditorComponent implements OnInit { this.selectedProperty = undefined; return; } - - const newProperty = new PropertyFEModel(this.selectedServiceProperties.find(property => property.name === this.currentRule.servicePropertyName)); + let newProperty; + if (this.filterType === FilterType.CAPABILITY) { + const currentProperty = this.capabilityNameAndPropertiesMap.get(this.currentRule.capabilityName) + .find(property => property.name === this.currentRule.servicePropertyName); + newProperty = new PropertyFEModel(currentProperty); + } else { + newProperty = new PropertyFEModel(this.selectedInstanceProperties.find(property => property.name === this.currentRule.servicePropertyName)); + } newProperty.value = undefined; newProperty.toscaFunction = undefined; if (typeof this.currentRule.value === 'string') { newProperty.value = this.currentRule.value; - } else if (this.isValueToscaFunction(newProperty.value)) { - newProperty.toscaFunction = this.currentRule.value; - newProperty.value = (this.currentRule.value).buildValueString(); + this.propertiesUtils.initValueObjectRef(newProperty); + } else if (ToscaFunctionHelper.isValueToscaFunction(this.currentRule.value)) { + newProperty.toscaFunction = ToscaFunctionHelper.convertObjectToToscaFunction(this.currentRule.value); + newProperty.value = newProperty.toscaFunction.buildValueString(); } else { newProperty.value = JSON.stringify(this.currentRule.value); + this.propertiesUtils.initValueObjectRef(newProperty); } - this.propertiesUtils.initValueObjectRef(newProperty); + this.selectedProperty = newProperty; } @@ -179,21 +231,21 @@ export class ServiceDependenciesEditorComponent implements OnInit { return; } - const newProperty = new PropertyFEModel(this.selectedServiceProperties.find(property => property.name === this.currentRule.servicePropertyName)); + let newProperty; + if (this.filterType === FilterType.CAPABILITY) { + const currentProperty = this.capabilityNameAndPropertiesMap.get(this.currentRule.capabilityName) + .find(property => property.name === this.currentRule.servicePropertyName); + newProperty = new PropertyFEModel(currentProperty); + } else { + newProperty = new PropertyFEModel(this.selectedInstanceProperties.find(property => property.name === this.currentRule.servicePropertyName)); + } newProperty.value = undefined; newProperty.toscaFunction = undefined; - if (this.isValueToscaFunction(newProperty.value)) { - newProperty.toscaFunction = this.currentRule.value; - } this.propertiesUtils.initValueObjectRef(newProperty); this.selectedProperty = newProperty; } - isValueToscaFunction(value: any): boolean { - return value instanceof Object && 'type' in value && (Object).values(ToscaFunctionType).includes(value.type); - } - isStaticSource(): boolean { return this.selectedSourceType === SourceType.STATIC } @@ -235,4 +287,15 @@ export class ServiceDependenciesEditorComponent implements OnInit { this.updateSelectedProperty(); } + private resetSelectedProperty(): void { + this.currentRule.servicePropertyName = undefined; + this.selectedProperty = undefined; + this.onPropertyChange(); + } + } + +export enum FilterType { + CAPABILITY, + PROPERTY +} \ No newline at end of file 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 5f6f074f5e..b6eb857471 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 @@ -6,6 +6,7 @@ * SDC * ================================================================================ * Copyright (C) 2017 AT&T Intellectual Property. All rights reserved. + * Modification Copyright (C) 2022 Nordix Foundation. * ================================================================================ * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -57,7 +58,6 @@ import {ConsumptionInput} from "../../components/logic/service-consumption/servi import {PolicyInstance} from "../../../models/graph/zones/policy-instance"; import {PropertyBEModel} from "../../../models/properties-inputs/property-be-model"; import {map} from "rxjs/operators"; -import {CapabilityFilterConstraint} from "../../../models/capability-filter-constraint"; import {BEInterfaceOperationModel, InterfaceOperationModel} from "../../../models/interfaceOperation"; import {AttributeBEModel} from "../../../models/attributes-outputs/attribute-be-model"; import {InstanceAttributesAPIMap} from "../../../models/attributes-outputs/attribute-fe-map"; @@ -481,7 +481,7 @@ export class TopologyTemplateService { return this.http.post(this.baseUrl + this.getServerTypeUrl(componentType) + componentMetaDataId + '/componentInstance/' + componentInstanceId + '/' + constraintType + '/nodeFilter', constraint); } - createServiceFilterCapabilitiesConstraints(componentMetaDataId: string, componentInstanceId: string, constraint: CapabilityFilterConstraint, componentType: string, constraintType: string): Observable { + createServiceFilterCapabilitiesConstraints(componentMetaDataId: string, componentInstanceId: string, constraint: FilterConstraint, componentType: string, constraintType: string): Observable { return this.http.post(this.baseUrl + this.getServerTypeUrl(componentType) + componentMetaDataId + '/componentInstance/' + componentInstanceId + '/' + constraintType + '/nodeFilter', constraint); } @@ -489,7 +489,7 @@ export class TopologyTemplateService { return this.http.put(this.baseUrl + this.getServerTypeUrl(componentType) + componentMetaDataId + '/componentInstance/' + componentInstanceId + '/' + constraintType + '/' + constraintIndex + '/nodeFilter', constraint) } - updateServiceFilterCapabilitiesConstraint(componentMetaDataId: string, componentInstanceId: string, constraints: CapabilityFilterConstraint, componentType: string, constraintType: string, constraintIndex: number):Observable{ + updateServiceFilterCapabilitiesConstraint(componentMetaDataId: string, componentInstanceId: string, constraints: FilterConstraint, componentType: string, constraintType: string, constraintIndex: number):Observable{ return this.http.put(this.baseUrl + this.getServerTypeUrl(componentType) + componentMetaDataId + '/componentInstance/' + componentInstanceId + '/' + constraintType + '/' + constraintIndex + '/nodeFilter', constraints) } diff --git a/catalog-ui/src/app/utils/filter-constraint-helper.ts b/catalog-ui/src/app/utils/filter-constraint-helper.ts index bdb3f9ec7a..f1207084a7 100644 --- a/catalog-ui/src/app/utils/filter-constraint-helper.ts +++ b/catalog-ui/src/app/utils/filter-constraint-helper.ts @@ -1,37 +1,42 @@ +/* + * - + * ============LICENSE_START======================================================= + * Copyright (C) 2022 Nordix Foundation. + * ================================================================================ + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + * SPDX-License-Identifier: Apache-2.0 + * ============LICENSE_END========================================================= + */ + import {FilterConstraint} from "../models/filter-constraint"; -import {ToscaFunctionType} from "../models/tosca-function-type.enum"; -import {ToscaConcatFunction} from "../models/tosca-concat-function"; -import {ToscaGetFunction} from "../models/tosca-get-function"; -import {YamlFunction} from "../models/yaml-function"; -import {CapabilityFilterConstraint} from "../models/capability-filter-constraint"; +import {ToscaFunctionHelper} from "./tosca-function-helper"; export class FilterConstraintHelper { - public static buildFilterConstraintLabel(constraint: FilterConstraint | CapabilityFilterConstraint): string { + public static buildFilterConstraintLabel(constraint: FilterConstraint): string { let value; - if (this.isValueToscaFunction(constraint.value)) { - switch (constraint.value.type) { - case ToscaFunctionType.CONCAT: - value = new ToscaConcatFunction(constraint.value).buildValueString(); - break; - case ToscaFunctionType.GET_PROPERTY: - case ToscaFunctionType.GET_INPUT: - case ToscaFunctionType.GET_ATTRIBUTE: - value = new ToscaGetFunction(constraint.value).buildValueString(); - break; - case ToscaFunctionType.YAML: - value = new YamlFunction(constraint.value).buildValueString(); - break; - case ToscaFunctionType.STRING: - value = constraint.value.value; - break; - default: - value = JSON.stringify(constraint.value, null, 4); + if (ToscaFunctionHelper.isValueToscaFunction(constraint.value)) { + const toscaFunction = ToscaFunctionHelper.convertObjectToToscaFunction(constraint.value); + if (toscaFunction) { + value = toscaFunction.buildValueString(); + } else { + value = JSON.stringify(constraint.value, null, 4); } } else { value = JSON.stringify(constraint.value, null, 4); } - if (constraint instanceof CapabilityFilterConstraint) { + if (constraint.capabilityName) { return `${constraint.capabilityName}: ${constraint.servicePropertyName} ${this.convertToSymbol(constraint.constraintOperator)} ${value}`; } @@ -40,25 +45,21 @@ export class FilterConstraintHelper { public static convertToSymbol(constraintOperator: string) { switch (constraintOperator) { - case OPERATOR_TYPES.LESS_THAN: return '<'; - case OPERATOR_TYPES.EQUAL: return '='; - case OPERATOR_TYPES.GREATER_THAN: return '>'; - case OPERATOR_TYPES.GREATER_OR_EQUAL: return '>='; - case OPERATOR_TYPES.LESS_OR_EQUAL: return '<='; + case ConstraintOperatorType.LESS_THAN: return '<'; + case ConstraintOperatorType.EQUAL: return '='; + case ConstraintOperatorType.GREATER_THAN: return '>'; + case ConstraintOperatorType.GREATER_OR_EQUAL: return '>='; + case ConstraintOperatorType.LESS_OR_EQUAL: return '<='; } } - private static isValueToscaFunction(value: any): boolean { - return value instanceof Object && 'type' in value && (Object).values(ToscaFunctionType).includes(value.type); - } - } -export const OPERATOR_TYPES = { - EQUAL: 'equal', - GREATER_THAN: 'greater_than', - LESS_THAN: 'less_than', - GREATER_OR_EQUAL: 'greater_or_equal', - LESS_OR_EQUAL: 'less_or_equal' -}; +export enum ConstraintOperatorType { + EQUAL = 'equal', + GREATER_THAN = 'greater_than', + LESS_THAN = 'less_than', + GREATER_OR_EQUAL = 'greater_or_equal', + LESS_OR_EQUAL = 'less_or_equal' +} diff --git a/catalog-ui/src/app/utils/tosca-function-helper.ts b/catalog-ui/src/app/utils/tosca-function-helper.ts new file mode 100644 index 0000000000..714f22ef57 --- /dev/null +++ b/catalog-ui/src/app/utils/tosca-function-helper.ts @@ -0,0 +1,64 @@ +/* + * - + * ============LICENSE_START======================================================= + * Copyright (C) 2022 Nordix Foundation. + * ================================================================================ + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + * SPDX-License-Identifier: Apache-2.0 + * ============LICENSE_END========================================================= + */ + +import {ToscaFunctionType} from "../models/tosca-function-type.enum"; +import {ToscaConcatFunction} from "../models/tosca-concat-function"; +import {ToscaGetFunction} from "../models/tosca-get-function"; +import {YamlFunction} from "../models/yaml-function"; +import {ToscaFunction} from "../models/tosca-function"; + +export class ToscaFunctionHelper { + + public static convertObjectToToscaFunction(value: any): ToscaFunction { + if (!value || !this.isValueToscaFunction(value)) { + return undefined; + } + + switch (value.type) { + case ToscaFunctionType.CONCAT: + return new ToscaConcatFunction(value); + case ToscaFunctionType.GET_PROPERTY: + case ToscaFunctionType.GET_INPUT: + case ToscaFunctionType.GET_ATTRIBUTE: + return new ToscaGetFunction(value); + case ToscaFunctionType.YAML: + return new YamlFunction(value); + case ToscaFunctionType.STRING: + return { + type: ToscaFunctionType.STRING, + value: value.value, + buildValueString(): string { + return this.value; + }, + buildValueObject(): Object { + return this.value; + } + }; + default: + return undefined; + } + } + + public static isValueToscaFunction(value: any): boolean { + return value instanceof Object && 'type' in value && (Object).values(ToscaFunctionType).includes(value.type); + } + +} diff --git a/catalog-ui/src/assets/languages/en_US.json b/catalog-ui/src/assets/languages/en_US.json index 13c8669dee..71f2b05efd 100644 --- a/catalog-ui/src/assets/languages/en_US.json +++ b/catalog-ui/src/assets/languages/en_US.json @@ -566,6 +566,7 @@ "VALUE_LABEL": "Value", "VALUE_EXPRESSION_LABEL": "Value Expression", "OPERATOR_LABEL": "Operator", + "CAPABILITY_LABEL": "Capability", "=========== SERVICE IMPORT ===========": "", "IMPORT_FAILURE_MESSAGE_TEXT": "Import Failure - error reading CSAR" } diff --git a/integration-tests/src/test/java/org/onap/sdc/frontend/ci/tests/pages/ServiceDependenciesEditor.java b/integration-tests/src/test/java/org/onap/sdc/frontend/ci/tests/pages/ServiceDependenciesEditor.java index f5f58582ec..b0f0814b8c 100644 --- a/integration-tests/src/test/java/org/onap/sdc/frontend/ci/tests/pages/ServiceDependenciesEditor.java +++ b/integration-tests/src/test/java/org/onap/sdc/frontend/ci/tests/pages/ServiceDependenciesEditor.java @@ -25,6 +25,7 @@ import com.fasterxml.jackson.databind.json.JsonMapper; import java.util.List; import java.util.Map; import java.util.Map.Entry; +import java.util.Objects; import java.util.stream.Collectors; import lombok.AllArgsConstructor; import lombok.Getter; @@ -53,8 +54,11 @@ public class ServiceDependenciesEditor extends AbstractPageObject { */ public List getPropertySelectOptions() { return new Select(webDriver.findElement(By.xpath(XpathSelector.SERVICE_PROPERTY_NAME.xPath))) - .getOptions().stream() - .map(option -> option.getAttribute("innerText")).collect(Collectors.toList()); + .getOptions().stream() + .map(option -> option.getAttribute("innerText")) + .filter(Objects::nonNull) + .filter(option -> !option.startsWith("Select")) + .collect(Collectors.toList()); } public void addProperty(final ServiceDependencyProperty property) { -- cgit 1.2.3-korg