Support TOSCA functions in Node Capability Filters 22/130822/8
authorandre.schmid <andre.schmid@est.tech>
Thu, 8 Sep 2022 17:55:08 +0000 (18:55 +0100)
committerMichael Morris <michael.morris@est.tech>
Mon, 19 Sep 2022 08:38:43 +0000 (08:38 +0000)
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 <andre.schmid@est.tech>
33 files changed:
catalog-be/src/main/docker/backend/chef-repo/cookbooks/sdc-catalog-be/files/default/error-configuration.yaml
catalog-be/src/main/java/org/openecomp/sdc/be/components/impl/ComponentNodeFilterBusinessLogic.java
catalog-be/src/main/java/org/openecomp/sdc/be/components/impl/NodeFilterUploadCreator.java
catalog-be/src/main/java/org/openecomp/sdc/be/components/impl/utils/CINodeFilterUtils.java
catalog-be/src/main/java/org/openecomp/sdc/be/components/validation/NodeFilterValidator.java
catalog-be/src/main/java/org/openecomp/sdc/be/servlets/ComponentNodeFilterServlet.java
catalog-be/src/main/resources/config/error-configuration.yaml
catalog-be/src/test/java/org/openecomp/sdc/be/components/impl/ComponentNodeFilterBusinessLogicTest.java
catalog-be/src/test/java/org/openecomp/sdc/be/servlets/ComponentNodeFilterServletTest.java
catalog-be/src/test/resources/config/catalog-be/error-configuration.yaml
catalog-dao/src/main/java/org/openecomp/sdc/be/dao/api/ActionStatus.java
catalog-model/src/main/java/org/openecomp/sdc/be/model/jsonjanusgraph/operations/NodeFilterOperation.java
catalog-model/src/test/java/org/openecomp/sdc/be/model/jsonjanusgraph/operations/NodeFilterOperationTest.java
catalog-ui/src/app/models/capability-filter-constraint.ts [deleted file]
catalog-ui/src/app/models/filter-constraint.ts
catalog-ui/src/app/models/ui-models/constraint-object-ui.ts [deleted file]
catalog-ui/src/app/models/ui-models/property-filter-constraint-ui.ts [new file with mode: 0644]
catalog-ui/src/app/ng2/app.module.ts
catalog-ui/src/app/ng2/components/logic/service-dependencies/service-dependencies.component.ts
catalog-ui/src/app/ng2/components/logic/substitution-filter/substitution-filter.component.ts
catalog-ui/src/app/ng2/components/ui/form-components/dropdown/ui-element-dropdown.component.html
catalog-ui/src/app/ng2/pages/composition/capabilities-filter-properties-editor/capabilities-filter-properties-editor.component.html [deleted file]
catalog-ui/src/app/ng2/pages/composition/capabilities-filter-properties-editor/capabilities-filter-properties-editor.component.less [deleted file]
catalog-ui/src/app/ng2/pages/composition/capabilities-filter-properties-editor/capabilities-filter-properties-editor.component.ts [deleted file]
catalog-ui/src/app/ng2/pages/composition/capabilities-filter-properties-editor/capabilities-filter-properties-editor.module.ts [deleted file]
catalog-ui/src/app/ng2/pages/composition/panel/panel-tabs/service-dependencies-tab/service-dependencies-tab.component.ts
catalog-ui/src/app/ng2/pages/service-dependencies-editor/service-dependencies-editor.component.html
catalog-ui/src/app/ng2/pages/service-dependencies-editor/service-dependencies-editor.component.ts
catalog-ui/src/app/ng2/services/component-services/topology-template.service.ts
catalog-ui/src/app/utils/filter-constraint-helper.ts
catalog-ui/src/app/utils/tosca-function-helper.ts [new file with mode: 0644]
catalog-ui/src/assets/languages/en_US.json
integration-tests/src/test/java/org/onap/sdc/frontend/ci/tests/pages/ServiceDependenciesEditor.java

index 7eb5ee4..7b3ade8 100644 (file)
@@ -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
index ff65d84..457f438 100644 (file)
@@ -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<CINodeFilterDataDefinition> 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<CINodeFilterDataDefinition, StorageOperationStatus> 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<CINodeFilterDataDefinition> 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<CINodeFilterDataDefinition> 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,
index f34091d..9cdf07c 100644 (file)
@@ -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<String, Object> entry = map.entrySet().iterator().next();
             final Object propertyConstraintClauses = entry.getValue();
             if (propertyConstraintClauses instanceof Map) {
-                final List<String> propertyFilterConstraintList = new ArrayList<>();
-                propertyFilterConstraintList.add(valueToProperty(map));
-                retVal.add(new UploadNodeFilterPropertyInfo(entry.getKey(), propertyFilterConstraintList));
+                retVal.add(new UploadNodeFilterPropertyInfo(entry.getKey(), List.of(valueToProperty(map))));
             } else if (propertyConstraintClauses instanceof List) {
-                final List<String> propertyFilterConstraintList = ((List<Object>) propertyConstraintClauses).stream()
+                ((List<Object>) 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;
index 5ac9bcd..6f0472d 100644 (file)
@@ -60,15 +60,16 @@ public class CINodeFilterUtils {
     private RequirementNodeFilterCapabilityDataDefinition convertCapability(UploadNodeFilterCapabilitiesInfo capability) {
         RequirementNodeFilterCapabilityDataDefinition retVal = new RequirementNodeFilterCapabilityDataDefinition();
         retVal.setName(capability.getName());
-        List<PropertyFilterDataDefinition> props = capability.getProperties().stream().map(this::buildProperty)
+        List<PropertyFilterDataDefinition> propertyFilterList = capability.getProperties().stream()
+            .map(filterPropertyInfo -> buildProperty(capability.getName(), filterPropertyInfo))
             .collect(Collectors.toList());
         ListDataDefinition<PropertyFilterDataDefinition> 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<String> 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())
             );
         }
index 12b58de..b7b2452 100644 (file)
@@ -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<? extends PropertyDefinition> targetComponentInstanceProperty =
-            parentComponent.getComponentInstancesProperties()
-                .get(componentInstanceId).stream()
+        final Optional<? extends PropertyDefinition> 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) {
index 80c806f..d69a7d3 100644 (file)
@@ -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<CINodeFilterDataDefinition> 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<CINodeFilterDataDefinition> 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));
index 81e302f..d31d4a6 100644 (file)
@@ -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
index 1bf075e..e3e1735 100644 (file)
@@ -274,7 +274,7 @@ class ComponentNodeFilterBusinessLogicTest extends BaseBusinessLogicMock {
 
         final Optional<CINodeFilterDataDefinition> 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<CINodeFilterDataDefinition> 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<CINodeFilterDataDefinition> 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);
index 4925210..29e3a54 100644 (file)
@@ -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,
index 81e302f..d31d4a6 100644 (file)
@@ -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
index 6208f11..2f5f175 100644 (file)
@@ -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
index 3dc2a73..f1de061 100644 (file)
@@ -84,13 +84,9 @@ public class NodeFilterOperation extends BaseOperation {
                                                                                        final int propertyIndex,
                                                                                        final NodeFilterConstraintType nodeFilterConstraintType) {
         if (NodeFilterConstraintType.PROPERTIES.equals(nodeFilterConstraintType)) {
-            final ListDataDefinition<PropertyFilterDataDefinition> properties = nodeFilterDataDefinition.getProperties();
-            properties.getListToscaDataDefinition().remove(propertyIndex);
-            nodeFilterDataDefinition.setProperties(properties);
+            nodeFilterDataDefinition.getProperties().getListToscaDataDefinition().remove(propertyIndex);
         } else if (NodeFilterConstraintType.CAPABILITIES.equals(nodeFilterConstraintType)) {
-            final ListDataDefinition<RequirementNodeFilterCapabilityDataDefinition> 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<RequirementNodeFilterCapabilityDataDefinition> existingCap = capabilities
                 .getListToscaDataDefinition().stream()
                 .filter(def -> def.getName().equals(requirementNodeFilterCapabilityDataDefinition.getName())).findAny();
-        
+
         if (existingCap.isPresent()) {
             final ListDataDefinition<PropertyFilterDataDefinition> newProperties  = requirementNodeFilterCapabilityDataDefinition.getProperties();
             final ListDataDefinition<PropertyFilterDataDefinition> 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<RequirementNodeFilterCapabilityDataDefinition> filtersByCapability =
+            nodeFilterDataDefinition.getCapabilities().getListToscaDataDefinition();
+        for (final RequirementNodeFilterCapabilityDataDefinition capabilityFilterGroup : filtersByCapability) {
+            final List<PropertyFilterDataDefinition> capabilityFilters = capabilityFilterGroup.getProperties().getListToscaDataDefinition();
+            if (isFilterInCapabilityGroup(currentFilterCountdown, capabilityFilters)) {
+                capabilityFilters.remove(currentFilterCountdown);
+                break;
+            } else {
+                currentFilterCountdown = getRemainingFilterCount(currentFilterCountdown, capabilityFilters);
+            }
+        }
+    }
+
+    private boolean isFilterInCapabilityGroup(int currentFilterCount, List<PropertyFilterDataDefinition> capabilityFilters) {
+        return capabilityFilters.size() > currentFilterCount;
+    }
+
+    private int getRemainingFilterCount(int currentFilterCount, final List<PropertyFilterDataDefinition> capabilityFilters) {
+        return currentFilterCount - capabilityFilters.size();
+    }
+
     private Either<CINodeFilterDataDefinition, StorageOperationStatus> addOrUpdateNodeFilter(final boolean isUpdateAction, final String componentId,
                                                                                              final String componentInstanceId,
                                                                                              final CINodeFilterDataDefinition ciNodeFilterDataDefinition) {
index bd16016..3df2795 100644 (file)
  */
 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<RequirementNodeFilterCapabilityDataDefinition>();
+
+        var capabilityFilter1 = new RequirementNodeFilterCapabilityDataDefinition();
+        final var propertyFilterList = new ListDataDefinition<PropertyFilterDataDefinition>();
+        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<PropertyFilterDataDefinition>();
+        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<CINodeFilterDataDefinition, StorageOperationStatus> 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 (file)
index 64d9913..0000000
+++ /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;
-    }
-}
index a118c97..69ad90c 100644 (file)
@@ -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 (file)
index 48cf2ab..0000000
+++ /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 (file)
index 0000000..f47677b
--- /dev/null
@@ -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
index 707e328..7153f0a 100644 (file)
 
 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,
index 04c7a3a..50ea60e 100644 (file)
@@ -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.
  * 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<string, PropertyModel[]>;
     @Output() updateRulesListEvent: EventEmitter<FilterConstraint[]> = new EventEmitter<FilterConstraint[]>();
     @Output() updateNodeFilterProperties: EventEmitter<FilterConstraint[]> = new EventEmitter<FilterConstraint[]>();
-    @Output() updateNodeFilterCapabilities: EventEmitter<CapabilityFilterConstraintUI[]> = new EventEmitter<CapabilityFilterConstraintUI[]>();
+    @Output() updateNodeFilterCapabilities: EventEmitter<PropertyFilterConstraintUi[]> = new EventEmitter<PropertyFilterConstraintUi[]>();
     @Output() loadRulesListEvent:EventEmitter<any> = new EventEmitter();
     @Output() dependencyStatus = new EventEmitter<boolean>();
 
@@ -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
index 53563e0..c1743e5 100644 (file)
 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();
index 9dca01e..7095e02 100644 (file)
@@ -15,5 +15,5 @@
   -->
   
 <select name='{{name}}' [(ngModel)]="value" (change)="onChange()"  [ngClass]="{'disabled':readonly}" [attr.data-tests-id]="'value-' + testId">
-  <option *ngFor="let ddvalue of values" [ngValue]="ddvalue.label != undefined ? ddvalue.value : ddvalue" [hidden]="ddvalue.hidden" [selected] = "ddvalue.selected">{{ddvalue.label||ddvalue}}</option>
+  <option *ngFor="let ddvalue of values" [ngValue]="ddvalue.label != undefined ? ddvalue.value : ddvalue" [hidden]="ddvalue.hidden" [selected] = "ddvalue.selected || ddvalue.value === value">{{ddvalue.label||ddvalue}}</option>
 </select>
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 (file)
index 1dcbc16..0000000
+++ /dev/null
@@ -1,81 +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.
- * ============LICENSE_END=========================================================
--->
-
-<div class="app-capabilities-filter-properties-editor">
-  <form class="w-sdc-form">
-    <loader [display]="isLoading" [size]="'large'" [relative]="true"></loader>
-    <div class="i-sdc-form-content">
-      <div class="rule-builder-content">
-        <div class="i-sdc-form-item rule-input-field">
-          <label class="i-sdc-form-label required">{{currentServiceName}} Capabilities</label>
-          <ui-element-dropdown class="i-sdc-form-select" class="rule-assigned-value"
-                               [(value)]="currentRule.capabilityName"
-                               [values]="capabilitiesNames"
-                               (elementChanged)="onCapabilityNameChanged($event.value)">
-          </ui-element-dropdown>
-        </div>
-
-        <div class="i-sdc-form-item rule-input-field">
-          <label class="i-sdc-form-label required">Capability Properties</label>
-          <ui-element-dropdown class="i-sdc-form-select" class="rule-assigned-value"
-                               [(value)]="this.currentRule.servicePropertyName"
-                               [values]="capabilityProperties"
-                               (change)="onServicePropertyChanged()">
-          </ui-element-dropdown>
-        </div>
-
-        <div class="i-sdc-form-item rule-input-field operator">
-          <ui-element-dropdown class="i-sdc-form-select"
-                               [values]="operatorTypes"
-                               [(value)]="currentRule.constraintOperator">
-          </ui-element-dropdown>
-        </div>
-
-        <div class="i-sdc-form-item rule-input-field">
-          <label class="i-sdc-form-label required" >Source</label>
-          <ui-element-dropdown class="i-sdc-form-select"
-                               [values]="sourceTypes"
-                               [(value)]="currentRule.sourceName"
-                               (change)="onSelectSourceType()">
-          </ui-element-dropdown>
-        </div>
-
-        <div class="rule-input-field assigned-value-field">
-          <label class="i-sdc-form-label required" >{{assignedValueLabel}}</label>
-          <dynamic-element
-              *ngIf="currentRule.sourceType === SOURCE_TYPES.STATIC.value"
-              [(value)]="currentRule.value"
-              class="rule-assigned-value"
-              data-tests-id="ruleAssignedValue"
-              (elementChanged)="onValueChange($event.isValid)"
-              [type]="selectedCapabilitiesPropertyObject ? selectedCapabilitiesPropertyObject.type : 'string'">
-          </dynamic-element>
-          <ui-element-dropdown *ngIf="currentRule.sourceType !== SOURCE_TYPES.STATIC.value"
-                               class="rule-assigned-value"
-                               data-tests-id="ruleAssignedValue"
-                               [(value)]="currentRule.value"
-                               [values]="listOfValuesToAssign">
-          </ui-element-dropdown>
-        </div>
-      </div>
-    </div>
-  </form>
-
-</div>
diff --git a/catalog-ui/src/app/ng2/pages/composition/capabilities-filter-properties-editor/capabilities-filter-properties-editor.component.less b/catalog-ui/src/app/ng2/pages/composition/capabilities-filter-properties-editor/capabilities-filter-properties-editor.component.less
deleted file mode 100644 (file)
index 188fb7b..0000000
+++ /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 (file)
index b59591b..0000000
+++ /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<string, PropertyModel[]>,
-  };
-  currentServiceName: string;
-  selectedServiceProperties: PropertyBEModel[];
-  operatorTypes: DropdownValue[];
-  sourceTypes: UIDropDownSourceTypesElement[] = [];
-  currentRule: CapabilityFilterConstraintUI;
-  currentIndex: number;
-  listOfValuesToAssign: DropdownValue[];
-  listOfSourceOptions: PropertyBEModel[];
-  assignedValueLabel: string;
-  serviceRulesList: CapabilityFilterConstraintUI[];
-
-  capabilitiesNames: string[];
-  selectedPropertiesByCapabilityName: Array<PropertyModel>;
-  selectedCapabilityName: string;
-  capabilityProperties: DropdownValue[];
-
-  selectedCapabilitiesPropertyObject: PropertyBEModel;
-
-  SOURCE_TYPES = {
-    STATIC: {label: 'Static', value: 'static'},
-    SERVICE_PROPERTY: {label: 'Service Property', value: 'property'},
-    CAPABILITY_NAME: {label: 'Name', value: 'name'}
-  };
-
-  ngOnInit() {
-    this.capabilitiesNames = Array.from(this.input.componentInstanceCapabilitiesMap.keys());
-    this.currentIndex = this.input.serviceRuleIndex;
-    this.serviceRulesList = this.input.serviceRules;
-    this.currentRule = this.serviceRulesList && this.input.serviceRuleIndex >= 0 ?
-        this.serviceRulesList[this.input.serviceRuleIndex] :
-        new 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 (file)
index 27bcb8a..0000000
+++ /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 {
-}
index ce1a43d..7ca4604 100644 (file)
@@ -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<string, PropertyModel[]> = 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<CapabilityFilterConstraint>):void => {
+    public updateSelectedInstanceCapabilitiesConstraints = (constraintsList:Array<FilterConstraint>):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();
     }
index 4e6993a..922cda6 100644 (file)
@@ -1,3 +1,25 @@
+<!--
+  ~ -
+  ~  ============LICENSE_START=======================================================
+  ~  Copyright (C) 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.
+  ~  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=========================================================
+  -->
+
 <div class="service-dependencies-editor">
     <form class="w-sdc-form">
 
 
         <div class="i-sdc-form-content">
             <div class="rule-builder-content">
+                <div class="i-sdc-form-item rule-input-field property" *ngIf="filterType == FILTER_TYPE_CAPABILITY">
+                    <label class="i-sdc-form-label required">{{"CAPABILITY_LABEL" | translate}}</label>
+                    <ui-element-dropdown
+                        class="i-sdc-form-select"
+                        data-tests-id="servicePropertyName"
+                        [values]="capabilityDropdownList"
+                        [(value)]="currentRule.capabilityName"
+                        (change)="onCapabilityChange()">
+                    </ui-element-dropdown>
+                </div>
                 <div class="i-sdc-form-item rule-input-field property">
                     <label class="i-sdc-form-label required">{{"PROPERTY_LABEL" | translate}}</label>
                     <ui-element-dropdown
                             class="i-sdc-form-select"
                             data-tests-id="servicePropertyName"
-                            [values]="ddValueSelectedServicePropertiesNames"
+                            [values]="servicePropertyDropdownList"
                             [(value)]="currentRule.servicePropertyName"
-                            (change)="onServicePropertyChanged()">
+                            (change)="onPropertyChange()">
                     </ui-element-dropdown>
                 </div>
-
                 <div class="i-sdc-form-item rule-input-field operator">
                     <label class="i-sdc-form-label required">{{"OPERATOR_LABEL" | translate}}</label>
-                    <ui-element-dropdown class="i-sdc-form-select" data-tests-id="constraintOperator" [values]="operatorTypes" [(value)]="currentRule.constraintOperator"></ui-element-dropdown>
+                    <ui-element-dropdown class="i-sdc-form-select" data-tests-id="constraintOperator"
+                                         [testId]="'constraintOperator'"
+                                         [values]="operatorTypes" [(value)]="currentRule.constraintOperator"></ui-element-dropdown>
                 </div>
             </div>
             <div class="rule-builder-content">
index ba7a494..f8a2160 100644 (file)
@@ -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.
  * 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<string, PropertyModel[]>;
+  @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<string, InstanceFeDetails> = new Map<string, InstanceFeDetails>();
+  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, <InstanceFeDetails>{
@@ -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 = (<ToscaFunction>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 && (<any>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
index 5f6f074..b6eb857 100644 (file)
@@ -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<any>(this.baseUrl + this.getServerTypeUrl(componentType) + componentMetaDataId + '/componentInstance/' + componentInstanceId + '/' + constraintType + '/nodeFilter', constraint);
     }
 
-    createServiceFilterCapabilitiesConstraints(componentMetaDataId: string, componentInstanceId: string, constraint: CapabilityFilterConstraint, componentType: string, constraintType: string): Observable<any> {
+    createServiceFilterCapabilitiesConstraints(componentMetaDataId: string, componentInstanceId: string, constraint: FilterConstraint, componentType: string, constraintType: string): Observable<any> {
         return this.http.post<any>(this.baseUrl + this.getServerTypeUrl(componentType) + componentMetaDataId + '/componentInstance/' + componentInstanceId + '/' + constraintType + '/nodeFilter', constraint);
     }
 
@@ -489,7 +489,7 @@ export class TopologyTemplateService {
         return this.http.put<any>(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<any>{
+    updateServiceFilterCapabilitiesConstraint(componentMetaDataId: string, componentInstanceId: string, constraints: FilterConstraint, componentType: string, constraintType: string, constraintIndex: number):Observable<any>{
         return this.http.put<any>(this.baseUrl + this.getServerTypeUrl(componentType) + componentMetaDataId + '/componentInstance/' + componentInstanceId + '/' + constraintType + '/' + constraintIndex + '/nodeFilter', constraints)
     }
 
index bdb3f9e..f120708 100644 (file)
@@ -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 && (<any>Object).values(ToscaFunctionType).includes(value.type);
-    }
-
 }
 
-export const OPERATOR_TYPES = {
-    EQUAL: 'equal',
-    GREATER_THAN: 'greater_than',
-    LESS_THAN: 'less_than',
-    GREATER_OR_EQUAL: 'greater_or_equal',
-    LESS_OR_EQUAL: 'less_or_equal'
-};
+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 (file)
index 0000000..714f22e
--- /dev/null
@@ -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 <ToscaFunction> {
+                    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 && (<any>Object).values(ToscaFunctionType).includes(value.type);
+    }
+
+}
index 13c8669..71f2b05 100644 (file)
   "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"
 }
index f5f5858..b0f0814 100644 (file)
@@ -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<String> 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) {