Fix for substitution filter properties 28/114128/2
authorKrupaNagabhushan <krupa.nagabhushan@est.tech>
Thu, 17 Sep 2020 14:11:30 +0000 (15:11 +0100)
committerS�bastien Determe <sebastien.determe@intl.att.com>
Fri, 23 Oct 2020 14:49:33 +0000 (14:49 +0000)
Issue-ID: SDC-3325
Change-Id: If26bf895a0a2f914fb9c2b36e53466df9b7999fe
Signed-off-by: KrupaNagabhushan <krupa.nagabhushan@est.tech>
23 files changed:
catalog-be/src/main/java/org/openecomp/sdc/be/components/impl/ComponentSubstitutionFilterBusinessLogic.java
catalog-be/src/main/java/org/openecomp/sdc/be/components/validation/NodeFilterValidator.java
catalog-be/src/main/java/org/openecomp/sdc/be/datamodel/utils/UiComponentDataConverter.java
catalog-be/src/main/java/org/openecomp/sdc/be/servlets/ComponentSubstitutionFilterServlet.java
catalog-be/src/main/java/org/openecomp/sdc/be/tosca/ToscaExportHandler.java
catalog-be/src/main/java/org/openecomp/sdc/be/tosca/utils/SubstitutionFilterConverter.java
catalog-be/src/test/java/org/openecomp/sdc/be/components/impl/ComponentSubstitutionFilterBusinessLogicTest.java
catalog-be/src/test/java/org/openecomp/sdc/be/servlets/ComponentSubstitutionFilterServletTest.java
catalog-model/src/main/java/org/openecomp/sdc/be/model/Component.java
catalog-model/src/main/java/org/openecomp/sdc/be/model/ComponentInstance.java
catalog-model/src/main/java/org/openecomp/sdc/be/model/ComponentParametersView.java
catalog-model/src/main/java/org/openecomp/sdc/be/model/jsonjanusgraph/operations/SubstitutionFilterOperation.java
catalog-model/src/main/java/org/openecomp/sdc/be/model/jsonjanusgraph/utils/ModelConverter.java
catalog-ui/src/app/models/tosca-filter-constraint-type.enum.ts [new file with mode: 0644]
catalog-ui/src/app/ng2/components/logic/substitution-filter/substitution-filter.component.html
catalog-ui/src/app/ng2/components/logic/substitution-filter/substitution-filter.component.less
catalog-ui/src/app/ng2/components/logic/substitution-filter/substitution-filter.component.ts
catalog-ui/src/app/ng2/components/logic/substitution-filter/substitution-filter.module.ts
catalog-ui/src/app/ng2/pages/composition/panel/composition-panel.component.spec.ts
catalog-ui/src/app/ng2/pages/composition/panel/composition-panel.component.ts
catalog-ui/src/app/ng2/pages/composition/panel/panel-tabs/substitution-filter-tab/substitution-filter-tab.component.html
catalog-ui/src/app/ng2/pages/composition/panel/panel-tabs/substitution-filter-tab/substitution-filter-tab.component.ts
catalog-ui/src/app/ng2/services/component-services/topology-template.service.ts

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