Add dependent child service to service 25/77425/6
authorshrek2000 <orenkle@amdocs.com>
Tue, 29 Jan 2019 11:04:42 +0000 (13:04 +0200)
committerAvi Gaffa <avi.gaffa@amdocs.com>
Wed, 30 Jan 2019 12:18:32 +0000 (12:18 +0000)
Add dependent child service to service
Issue-ID: SDC-1987

Change-Id: Ic542fe1bc13f2b77df9944f05421a42b4b21c437
Signed-off-by: shrek2000 <orenkle@amdocs.com>
29 files changed:
catalog-be/src/main/java/org/openecomp/sdc/be/components/impl/ServiceBusinessLogic.java
catalog-be/src/main/java/org/openecomp/sdc/be/components/impl/utils/CINodeFilterUtils.java [new file with mode: 0644]
catalog-be/src/main/java/org/openecomp/sdc/be/components/impl/utils/NodeFilterConstraintAction.java [new file with mode: 0644]
catalog-be/src/main/java/org/openecomp/sdc/be/components/validation/NodeFilterValidator.java [new file with mode: 0644]
catalog-be/src/main/java/org/openecomp/sdc/be/datamodel/utils/ConstraintConvertor.java [new file with mode: 0644]
catalog-be/src/main/java/org/openecomp/sdc/be/servlets/ServiceFilterServlet.java [new file with mode: 0644]
catalog-be/src/main/java/org/openecomp/sdc/be/tosca/model/CapabilityFilter.java [new file with mode: 0644]
catalog-be/src/main/java/org/openecomp/sdc/be/tosca/model/NodeFilter.java [new file with mode: 0644]
catalog-be/src/main/java/org/openecomp/sdc/be/tosca/utils/NodeFilterConverter.java [new file with mode: 0644]
catalog-be/src/main/resources/config/error-configuration.yaml
catalog-be/src/test/java/org/openecomp/sdc/be/components/validation/NodeFilterValidationTest.java [new file with mode: 0644]
catalog-be/src/test/java/org/openecomp/sdc/be/tosca/model/ConstraintConvertorTest.java [new file with mode: 0644]
catalog-dao/src/main/java/org/openecomp/sdc/be/dao/api/ActionStatus.java
catalog-dao/src/main/java/org/openecomp/sdc/be/dao/jsongraph/types/EdgeLabelEnum.java
catalog-dao/src/main/java/org/openecomp/sdc/be/dao/jsongraph/types/VertexTypeEnum.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/UploadNodeFilterCapabilitiesInfo.java [new file with mode: 0644]
catalog-model/src/main/java/org/openecomp/sdc/be/model/UploadNodeFilterInfo.java [new file with mode: 0644]
catalog-model/src/main/java/org/openecomp/sdc/be/model/UploadNodeFilterPropertyInfo.java [new file with mode: 0644]
catalog-model/src/main/java/org/openecomp/sdc/be/model/jsontitan/operations/NodeFilterOperation.java [new file with mode: 0644]
catalog-model/src/main/java/org/openecomp/sdc/be/model/tosca/constraints/ConstraintType.java
catalog-model/src/main/java/org/openecomp/sdc/be/ui/model/UIConstraint.java [new file with mode: 0644]
catalog-model/src/main/java/org/openecomp/sdc/be/ui/model/UINodeFilter.java [new file with mode: 0644]
common-be/src/main/java/org/openecomp/sdc/be/datatypes/elements/CINodeFilterDataDefinition.java [new file with mode: 0644]
common-be/src/main/java/org/openecomp/sdc/be/datatypes/elements/RequirementNodeFilterCapabilityDataDefinition.java [new file with mode: 0644]
common-be/src/main/java/org/openecomp/sdc/be/datatypes/elements/RequirementNodeFilterPropertyDataDefinition.java [new file with mode: 0644]
common-be/src/main/java/org/openecomp/sdc/be/datatypes/enums/ComponentFieldsEnum.java
common-be/src/main/java/org/openecomp/sdc/be/datatypes/enums/JsonPresentationFields.java

index 8d4f896..9bf4429 100644 (file)
@@ -33,8 +33,10 @@ import org.openecomp.sdc.be.components.distribution.engine.INotificationData;
 import org.openecomp.sdc.be.components.distribution.engine.VfModuleArtifactPayload;
 import org.openecomp.sdc.be.components.health.HealthCheckBusinessLogic;
 import org.openecomp.sdc.be.components.impl.exceptions.ComponentException;
+import org.openecomp.sdc.be.components.impl.utils.NodeFilterConstraintAction;
 import org.openecomp.sdc.be.components.lifecycle.LifecycleChangeInfoWithAction;
 import org.openecomp.sdc.be.components.path.ForwardingPathValidator;
+import org.openecomp.sdc.be.components.validation.NodeFilterValidator;
 import org.openecomp.sdc.be.components.validation.ServiceDistributionValidation;
 import org.openecomp.sdc.be.config.BeEcompErrorManager;
 import org.openecomp.sdc.be.config.ConfigurationManager;
@@ -43,7 +45,9 @@ import org.openecomp.sdc.be.dao.cassandra.AuditCassandraDao;
 import org.openecomp.sdc.be.dao.jsongraph.types.JsonParseFlagEnum;
 import org.openecomp.sdc.be.datamodel.ServiceRelations;
 import org.openecomp.sdc.be.datamodel.utils.UiComponentDataConverter;
+import org.openecomp.sdc.be.datatypes.elements.CINodeFilterDataDefinition;
 import org.openecomp.sdc.be.datatypes.elements.ForwardingPathDataDefinition;
+import org.openecomp.sdc.be.datatypes.elements.RequirementNodeFilterPropertyDataDefinition;
 import org.openecomp.sdc.be.datatypes.enums.ComponentTypeEnum;
 import org.openecomp.sdc.be.datatypes.enums.InstantiationTypes;
 import org.openecomp.sdc.be.datatypes.enums.NodeTypeEnum;
@@ -54,6 +58,7 @@ import org.openecomp.sdc.be.impl.WebAppContextWrapper;
 import org.openecomp.sdc.be.model.*;
 import org.openecomp.sdc.be.model.category.CategoryDefinition;
 import org.openecomp.sdc.be.model.jsontitan.operations.ForwardingPathOperation;
+import org.openecomp.sdc.be.model.jsontitan.operations.NodeFilterOperation;
 import org.openecomp.sdc.be.model.jsontitan.operations.ToscaOperationFacade;
 import org.openecomp.sdc.be.model.operations.api.ICacheMangerOperation;
 import org.openecomp.sdc.be.model.operations.api.IElementOperation;
@@ -120,6 +125,10 @@ public class ServiceBusinessLogic extends ComponentBusinessLogic {
     private ForwardingPathValidator forwardingPathValidator;
     @Autowired
     private UiComponentDataConverter uiComponentDataConverter;
+    @Autowired
+    private NodeFilterOperation serviceFilterOperation;
+    @Autowired
+    private NodeFilterValidator serviceFilterValidator;
 
     public Either<Service, ResponseFormat> changeServiceDistributionState(String serviceId, String state, LifecycleChangeInfoWithAction commentObj, User user) {
 
@@ -2107,4 +2116,303 @@ public class ServiceBusinessLogic extends ComponentBusinessLogic {
         UiComponentDataTransfer dataTransfer = uiComponentDataConverter.getUiDataTransferFromServiceByParams(service, dataParamsToReturn);
         return Either.left(dataTransfer);
     }
+
+    public Either<String, ResponseFormat> deleteIfNotAlreadyDeletedServiceFilter(String serviceId, String resourceId, String userId, boolean lock) {
+        Service serviceToDelete = initServiceToDeleteServiceFilter(serviceId);
+        User user = validateUserExists(userId, "Create service Filter", false);
+
+        user =
+                validateUser(user, "deleteIfNotAlreadyDeletedServiceFilter", serviceToDelete, null, false);
+
+         Either<Service, StorageOperationStatus> storageStatus = toscaOperationFacade.getToscaElement(serviceId);
+        if (storageStatus.isRight()) {
+            return Either.right(componentsUtils.getResponseFormat(componentsUtils.convertFromStorageResponse(storageStatus.right().value(), ComponentTypeEnum.SERVICE), ""));
+        }
+        Service service = storageStatus.left().value();
+
+        Either<Boolean, ResponseFormat> response = serviceFilterValidator.validateComponentInstanceExist(service, resourceId);
+        if (storageStatus.isRight()) {
+            return Either.right(response.right().value());
+        }
+        final Optional<ComponentInstance> optionalComponentInstance = service.getComponentInstanceById(resourceId);
+        if (!optionalComponentInstance.isPresent() ){
+            return Either.right(componentsUtils.getResponseFormat(ActionStatus.GENERAL_ERROR));
+        }
+        CINodeFilterDataDefinition nodeFilter = optionalComponentInstance.get().getNodeFilter();
+        if (nodeFilter == null){
+            return Either.left(resourceId);
+        }
+
+        Either<String, StorageOperationStatus> result;
+        if (lock) {
+            Either<Boolean, ResponseFormat> lockResult = lockComponent(service.getUniqueId(), service, "Delete Service Filter from service");
+            if (lockResult.isRight()) {
+                titanDao.rollback();
+                return Either.right(componentsUtils.getResponseFormat(componentsUtils
+                                                                              .convertFromStorageResponse(storageStatus.right().value(), ComponentTypeEnum.SERVICE), ""));
+            }
+        }
+        try{
+            result = serviceFilterOperation.deleteNodeFilter(service , resourceId);
+            if (result.isRight()) {
+                log.debug("Failed to delete node filter in service {}. Response is {}. ", service.getName(), result.right().value());
+                titanDao.rollback();
+                return Either.right(componentsUtils.getResponseFormat(componentsUtils.convertFromStorageResponse(storageStatus.right().value(), ComponentTypeEnum.SERVICE)));
+            }
+            titanDao.commit();
+            log.debug("Node filter successfully changed in service {} . ", service.getSystemName());
+
+        } catch (Exception e){
+            log.error("Exception occurred during delete forwarding path : {}", e.getMessage(), e);
+            titanDao.rollback();
+            return Either.right(componentsUtils.getResponseFormat(ActionStatus.GENERAL_ERROR));
+        } finally {
+            graphLockOperation.unlockComponent(service.getUniqueId(), NodeTypeEnum.Service);
+        }
+        return Either.left(result.left().value());
+    }
+
+
+    private Service initServiceToDeleteServiceFilter(String serviceId) {
+        Service serviceToDelete = new Service();
+        serviceToDelete.setUniqueId(serviceId);
+        return serviceToDelete;
+    }
+
+
+    public Either<CINodeFilterDataDefinition, ResponseFormat> createIfNotAlreadyExistServiceFilter(String serviceId, String componentInstanceId, String userId, boolean lock) {
+        String errorContext =  "createIfNotAlreadyExistServiceFilter";
+        User user = validateUserExists(userId, "Create service Filter", false);
+
+        Either<Service, StorageOperationStatus> serviceEither = toscaOperationFacade.getToscaElement(serviceId);
+        if (serviceEither.isRight()) {
+            return Either.right(componentsUtils.getResponseFormat(componentsUtils.convertFromStorageResponse(serviceEither.right().value(), ComponentTypeEnum.SERVICE), ""));
+        }
+        final Service service = serviceEither.left().value();
+        validateUserAndRole(service, user, errorContext);
+
+        Optional<ComponentInstance> optionalComponentInstance = service.getComponentInstanceById(componentInstanceId);
+        if (!optionalComponentInstance.isPresent()){
+            return Either.right(ResponseFormatManager.getInstance().getResponseFormat(ActionStatus.NODE_FILTER_NOT_FOUND));
+        }
+        ComponentInstance componentInstance = optionalComponentInstance.get();
+        CINodeFilterDataDefinition serviceFilter = componentInstance.getNodeFilter();
+        if (serviceFilter != null){
+            return Either.left(serviceFilter);
+        }
+
+        Either<CINodeFilterDataDefinition, StorageOperationStatus> result;
+
+        Either<Boolean, ResponseFormat> lockResult = null;
+        if (lock) {
+            lockResult =
+                    lockComponent(service.getUniqueId(), service, "Create Service Filter");
+            if (lockResult.isRight()) {
+                log.debug("Failed to lock service {}. Response is {}. ", service.getName(),
+                        lockResult.right().value().getFormattedMessage());
+                return Either.right(lockResult.right().value());
+            } else {
+                log.debug("The service with system name {} locked. ", service.getSystemName());
+            }
+        }
+        CINodeFilterDataDefinition serviceFilterResult;
+        try {
+            result =  serviceFilterOperation.createNodeFilter(serviceId, componentInstanceId);
+            if (result.isRight()) {
+                titanDao.rollback();
+                return Either.right(componentsUtils.getResponseFormat(
+                        componentsUtils.convertFromStorageResponse(result.right().value(), ComponentTypeEnum.SERVICE),
+                        ""));
+            } else {
+                serviceFilterResult = result.left().value();
+            }
+            titanDao.commit();
+
+        } catch (Exception e) {
+            titanDao.rollback();
+            log.error("Exception occurred during add or update service filter property values: {}", e.getMessage(),
+                    e);
+            return Either.right(componentsUtils.getResponseFormat(ActionStatus.GENERAL_ERROR));
+
+        } finally {
+            if (lockResult != null && lockResult.isLeft() && lockResult.left().value()) {
+                graphLockOperation.unlockComponent(service.getUniqueId(), NodeTypeEnum.Service);
+            }
+        }
+        return Either.left(serviceFilterResult);
+    }
+
+
+    public Either<CINodeFilterDataDefinition, ResponseFormat> updateServiceFilter(String serviceId, String componentInstanceId,
+            List<String> constraints,  User inUser, boolean lock) {
+        String errorContext =  "createIfNotAlreadyExistServiceFilter";
+        Either<?, ResponseFormat> eitherCreator1 = null;
+        User user = validateUserExists(inUser, errorContext, true);
+        validateUserRole(user, Arrays.asList(Role.DESIGNER, Role.ADMIN));
+        if (eitherCreator1 != null && eitherCreator1.isRight()) {
+            return Either.right(eitherCreator1.right().value());
+        }
+
+        Either<Service, StorageOperationStatus> serviceStorageOperationStatusEither = toscaOperationFacade.getToscaElement(serviceId);
+
+        if(serviceStorageOperationStatusEither.isRight()){
+            StorageOperationStatus errorStatus = serviceStorageOperationStatusEither.right().value();
+            log.debug("Failed to fetch service information by service id, error {}", errorStatus);
+            return Either.right(componentsUtils.getResponseFormat(componentsUtils.convertFromStorageResponse(errorStatus)));
+        }
+        Service storedService = serviceStorageOperationStatusEither.left().value();
+
+        Either<Boolean, ResponseFormat> booleanResponseFormatEither =
+                serviceFilterValidator.validateNodeFilter(storedService, componentInstanceId, constraints,
+                        NodeFilterConstraintAction.UPDATE);
+        if(booleanResponseFormatEither.isRight()){
+            return Either.right(booleanResponseFormatEither.right().value());
+        }
+
+
+        Either<Boolean, ResponseFormat> lockResult = null;
+        if (lock) {
+            lockResult =
+                    lockComponent(storedService.getUniqueId(), storedService, "Add or Update Service Filter on Service");
+            if (lockResult.isRight()) {
+                log.debug("Failed to lock service {}. Response is {}. ", storedService.getName(),
+                        lockResult.right().value().getFormattedMessage());
+                return Either.right(lockResult.right().value());
+            } else {
+                log.debug("The service with system name {} locked. ", storedService.getSystemName());
+            }
+        }
+        Optional<ComponentInstance> componentInstanceOptional = storedService.getComponentInstanceById(componentInstanceId);
+        if (!componentInstanceOptional.isPresent()){
+            return  Either.right(ResponseFormatManager.getInstance().getResponseFormat(ActionStatus.NODE_FILTER_NOT_FOUND));
+        }
+        CINodeFilterDataDefinition serviceFilter = componentInstanceOptional.get().getNodeFilter();
+        if(serviceFilter == null){
+            return  Either.right(ResponseFormatManager.getInstance().getResponseFormat(ActionStatus.NODE_FILTER_NOT_FOUND));
+        }
+        CINodeFilterDataDefinition serviceFilterResult;
+        try {
+            List<RequirementNodeFilterPropertyDataDefinition> properties = (List<RequirementNodeFilterPropertyDataDefinition>) constraints.
+                                                                                                                                                  stream().map(this::getRequirementNodeFilterPropertyDataDefinition).collect(Collectors.toList());
+            Either<CINodeFilterDataDefinition, StorageOperationStatus>  result =  serviceFilterOperation.updateProperties(serviceId, componentInstanceId, serviceFilter ,properties);
+
+            if (result.isRight()) {
+                titanDao.rollback();
+                return Either.right(componentsUtils.getResponseFormat(
+                        componentsUtils.convertFromStorageResponse(result.right().value(), ComponentTypeEnum.SERVICE),
+                        ""));
+            } else {
+                serviceFilterResult = result.left().value();
+            }
+            titanDao.commit();
+
+        } catch (Exception e) {
+            titanDao.rollback();
+            log.error("Exception occurred during add or update service filter property values: {}", e.getMessage(),
+                    e);
+            return Either.right(componentsUtils.getResponseFormat(ActionStatus.GENERAL_ERROR));
+
+        } finally {
+            if (lockResult != null && lockResult.isLeft() && lockResult.left().value()) {
+                graphLockOperation.unlockComponent(storedService.getUniqueId(), NodeTypeEnum.Service);
+            }
+        }
+        return Either.left(serviceFilterResult);
+    }
+
+    private RequirementNodeFilterPropertyDataDefinition getRequirementNodeFilterPropertyDataDefinition(String constraint){
+        RequirementNodeFilterPropertyDataDefinition pdd = new RequirementNodeFilterPropertyDataDefinition();
+        pdd.setConstraints(Arrays.asList(constraint));
+        return pdd;
+    }
+
+    public Either<CINodeFilterDataDefinition, ResponseFormat> addOrDeleteServiceFilter(String serviceId, String componentInstanceId,
+            NodeFilterConstraintAction action, String constraint, int position, User inUser, boolean lock) {
+        String errorContext =  "createIfNotAlreadyExistServiceFilter";
+        Either<?, ResponseFormat> eitherCreator1 = null;
+        User user = validateUserExists(inUser, errorContext, true);
+        validateUserRole(user, Arrays.asList(Role.DESIGNER, Role.ADMIN));
+        if (eitherCreator1 != null && eitherCreator1.isRight()) {
+            return Either.right(eitherCreator1.right().value());
+        }
+
+        Either<Service, StorageOperationStatus> serviceStorageOperationStatusEither = toscaOperationFacade.getToscaElement(serviceId);
+
+        if(serviceStorageOperationStatusEither.isRight()){
+            StorageOperationStatus errorStatus = serviceStorageOperationStatusEither.right().value();
+            log.debug("Failed to fetch service information by service id, error {}", errorStatus);
+            return Either.right(componentsUtils.getResponseFormat(componentsUtils.convertFromStorageResponse(errorStatus)));
+        }
+        Service storedService = serviceStorageOperationStatusEither.left().value();
+
+        Either<Boolean, ResponseFormat> booleanResponseFormatEither =
+                serviceFilterValidator.validateNodeFilter(storedService, componentInstanceId,
+                        Collections.singletonList(constraint), action);
+        if(booleanResponseFormatEither.isRight()){
+            return Either.right(booleanResponseFormatEither.right().value());
+        }
+
+        Either<CINodeFilterDataDefinition, StorageOperationStatus> result;
+
+        Either<Boolean, ResponseFormat> lockResult = null;
+        if (lock) {
+            lockResult =
+                    lockComponent(storedService.getUniqueId(), storedService, "Add or Update Service Filter on Service");
+            if (lockResult.isRight()) {
+                log.debug("Failed to lock service {}. Response is {}. ", storedService.getName(),
+                        lockResult.right().value().getFormattedMessage());
+                return Either.right(lockResult.right().value());
+            } else {
+                log.debug("The service with system name {} locked. ", storedService.getSystemName());
+            }
+        }
+
+        Optional<ComponentInstance> componentInstanceOptional = storedService.getComponentInstanceById(componentInstanceId);
+        if (!componentInstanceOptional.isPresent()){
+            return  Either.right(ResponseFormatManager.getInstance().getResponseFormat(ActionStatus.NODE_FILTER_NOT_FOUND));
+        }
+        CINodeFilterDataDefinition serviceFilter = componentInstanceOptional.get().getNodeFilter();
+        if(serviceFilter == null){
+            return  Either.right(ResponseFormatManager.getInstance().getResponseFormat(ActionStatus.NODE_FILTER_NOT_FOUND));
+        }
+        CINodeFilterDataDefinition serviceFilterResult;
+        try {
+            switch (action) {
+                case ADD:
+                    RequirementNodeFilterPropertyDataDefinition newProperty = new RequirementNodeFilterPropertyDataDefinition();
+                    newProperty.setConstraints(Collections.singletonList(constraint));
+                    result = serviceFilterOperation.addNewProperty(serviceId, componentInstanceId,serviceFilter,newProperty);
+                    break;
+                case DELETE:
+                    result = serviceFilterOperation.deleteConstraint(serviceId, componentInstanceId, serviceFilter, position);
+                    break;
+                default:
+                    log.error("Unsupported operation "+action);
+                    return Either.right(componentsUtils.getResponseFormat(ActionStatus.GENERAL_ERROR));
+
+            }
+
+            if (result.isRight()) {
+                titanDao.rollback();
+                return Either.right(componentsUtils.getResponseFormat(
+                        componentsUtils.convertFromStorageResponse(result.right().value(), ComponentTypeEnum.SERVICE),
+                        ""));
+            } else {
+                serviceFilterResult = result.left().value();
+            }
+            titanDao.commit();
+
+        } catch (Exception e) {
+            titanDao.rollback();
+            log.error("Exception occurred during add or update node filter property values: {}", e.getMessage(),
+                    e);
+            return Either.right(componentsUtils.getResponseFormat(ActionStatus.GENERAL_ERROR));
+
+        } finally {
+            if (lockResult != null && lockResult.isLeft() && lockResult.left().value()) {
+                graphLockOperation.unlockComponent(storedService.getUniqueId(), NodeTypeEnum.Service);
+            }
+        }
+        return Either.left(serviceFilterResult);
+    }
 }
diff --git a/catalog-be/src/main/java/org/openecomp/sdc/be/components/impl/utils/CINodeFilterUtils.java b/catalog-be/src/main/java/org/openecomp/sdc/be/components/impl/utils/CINodeFilterUtils.java
new file mode 100644 (file)
index 0000000..73ec335
--- /dev/null
@@ -0,0 +1,87 @@
+/*
+ * Copyright © 2016-2018 European Support Limited
+ *
+ * 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.
+ */
+
+package org.openecomp.sdc.be.components.impl.utils;
+
+import java.util.List;
+import java.util.Map;
+import java.util.stream.Collectors;
+import org.openecomp.sdc.be.datatypes.elements.CINodeFilterDataDefinition;
+import org.openecomp.sdc.be.datatypes.elements.ListDataDefinition;
+import org.openecomp.sdc.be.datatypes.elements.RequirementNodeFilterCapabilityDataDefinition;
+import org.openecomp.sdc.be.datatypes.elements.RequirementNodeFilterPropertyDataDefinition;
+import org.openecomp.sdc.be.model.UploadNodeFilterCapabilitiesInfo;
+import org.openecomp.sdc.be.model.UploadNodeFilterInfo;
+import org.openecomp.sdc.be.model.UploadNodeFilterPropertyInfo;
+import org.openecomp.sdc.common.log.wrappers.Logger;
+
+public class CINodeFilterUtils {
+
+    Logger log = Logger.getLogger(CINodeFilterUtils.class);
+
+
+    public CINodeFilterDataDefinition getNodeFilterDataDefinition(
+            UploadNodeFilterInfo uploadNodeFilterInfo, String uniqueId) {
+        CINodeFilterDataDefinition nodeFilterDataDefinition =
+                new CINodeFilterDataDefinition();
+        nodeFilterDataDefinition.setName(uploadNodeFilterInfo.getName());
+        List<RequirementNodeFilterPropertyDataDefinition> collect =
+                uploadNodeFilterInfo.getProperties().stream().map(this::buildProperty).collect(Collectors.toList());
+        ListDataDefinition<RequirementNodeFilterPropertyDataDefinition> listDataDefinition = new ListDataDefinition<>();
+        listDataDefinition.getListToscaDataDefinition().addAll(collect);
+        nodeFilterDataDefinition.setProperties(listDataDefinition);
+        nodeFilterDataDefinition.setCapabilities(converCapabilties(uploadNodeFilterInfo.getCapabilities()));
+        nodeFilterDataDefinition.setID(uniqueId);
+        nodeFilterDataDefinition.setTosca_id(uploadNodeFilterInfo.getTosca_id());
+        return nodeFilterDataDefinition;
+    }
+
+    private ListDataDefinition<RequirementNodeFilterCapabilityDataDefinition> converCapabilties(
+            Map<String, UploadNodeFilterCapabilitiesInfo> capabilities) {
+        ListDataDefinition<RequirementNodeFilterCapabilityDataDefinition> listDataDefinition =
+                new ListDataDefinition<>();
+        for (UploadNodeFilterCapabilitiesInfo capability : capabilities.values()) {
+            RequirementNodeFilterCapabilityDataDefinition requirementNodeFilterCapabilityDataDefinition =
+                    convertCapability(capability);
+            listDataDefinition.add(requirementNodeFilterCapabilityDataDefinition);
+        }
+        return listDataDefinition;
+    }
+
+    private RequirementNodeFilterCapabilityDataDefinition convertCapability(
+            UploadNodeFilterCapabilitiesInfo capability) {
+        RequirementNodeFilterCapabilityDataDefinition retVal = new RequirementNodeFilterCapabilityDataDefinition();
+        retVal.setName(capability.getName());
+        List<RequirementNodeFilterPropertyDataDefinition> props =
+                capability.getProperties().stream().map(this::buildProperty).collect(Collectors.toList());
+        ListDataDefinition<RequirementNodeFilterPropertyDataDefinition> propsList = new ListDataDefinition<>();
+        propsList.getListToscaDataDefinition().addAll(props);
+        retVal.setProperties(propsList);
+        return retVal;
+    }
+
+
+    private RequirementNodeFilterPropertyDataDefinition buildProperty(
+            UploadNodeFilterPropertyInfo uploadNodeFilterPropertyInfo) {
+        RequirementNodeFilterPropertyDataDefinition retVal = new RequirementNodeFilterPropertyDataDefinition();
+        retVal.setName(uploadNodeFilterPropertyInfo.getName());
+        List<String> propertyConstraints = uploadNodeFilterPropertyInfo.getValues();
+        retVal.setConstraints(propertyConstraints);
+        return retVal;
+    }
+
+
+}
diff --git a/catalog-be/src/main/java/org/openecomp/sdc/be/components/impl/utils/NodeFilterConstraintAction.java b/catalog-be/src/main/java/org/openecomp/sdc/be/components/impl/utils/NodeFilterConstraintAction.java
new file mode 100644 (file)
index 0000000..32f49b3
--- /dev/null
@@ -0,0 +1,20 @@
+/*
+ * Copyright © 2016-2018 European Support Limited
+ *
+ * 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.
+ */
+package org.openecomp.sdc.be.components.impl.utils;
+
+public enum NodeFilterConstraintAction {
+    ADD,  DELETE, UPDATE
+}
diff --git a/catalog-be/src/main/java/org/openecomp/sdc/be/components/validation/NodeFilterValidator.java b/catalog-be/src/main/java/org/openecomp/sdc/be/components/validation/NodeFilterValidator.java
new file mode 100644 (file)
index 0000000..8d28088
--- /dev/null
@@ -0,0 +1,226 @@
+package org.openecomp.sdc.be.components.validation;
+
+import com.google.common.collect.ImmutableSet;
+import fj.data.Either;
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.List;
+import java.util.Objects;
+import java.util.Optional;
+import java.util.Set;
+import org.apache.commons.lang3.StringUtils;
+import org.openecomp.sdc.be.components.impl.ResponseFormatManager;
+import org.openecomp.sdc.be.components.impl.utils.NodeFilterConstraintAction;
+import org.openecomp.sdc.be.dao.api.ActionStatus;
+import org.openecomp.sdc.be.datamodel.utils.ConstraintConvertor;
+import org.openecomp.sdc.be.datatypes.elements.CINodeFilterDataDefinition;
+import org.openecomp.sdc.be.datatypes.elements.SchemaDefinition;
+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.jsontitan.operations.ToscaOperationFacade;
+import org.openecomp.sdc.be.model.tosca.ToscaPropertyType;
+import org.openecomp.sdc.be.ui.model.UIConstraint;
+import org.openecomp.sdc.exception.ResponseFormat;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Component;
+import org.springframework.util.CollectionUtils;
+
+@Component("NodeFilterValidator")
+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());
+    public static final Set<String> schemableTypes =
+            ImmutableSet.of(ToscaPropertyType.MAP.getType(), ToscaPropertyType.LIST.getType());
+    public static final Set<String> comparableConstraintsOperators =
+            ImmutableSet.of(ConstraintConvertor.GREATER_THAN_OPERATOR, ConstraintConvertor.LESS_THAN_OPERATOR);
+
+    @Autowired
+    protected ToscaOperationFacade toscaOperationFacade;
+
+    @Autowired
+    protected ComponentsUtils componentsUtils;
+
+    private static final Logger LOGGER = LoggerFactory.getLogger(NodeFilterValidator.class);
+
+    public Either<Boolean, ResponseFormat> validateComponentInstanceExist(Service service, String componentInstanceId) {
+        if (service == null || StringUtils.isEmpty(componentInstanceId)) {
+            LOGGER.debug("Input data cannot be empty");
+            return getErrorResponse(ActionStatus.NODE_FILTER_NOT_FOUND);
+        }
+        if (CollectionUtils.isEmpty(service.getComponentInstances())) {
+            LOGGER.debug("Component Instance list is empty");
+            return getErrorResponse(ActionStatus.NODE_FILTER_NOT_FOUND);
+        }
+        boolean found =
+                service.getComponentInstances().stream().anyMatch(ci -> ci.getUniqueId().equals(componentInstanceId));
+        if (!found) {
+            LOGGER.debug("Component Instance list is empty");
+            return getErrorResponse(ActionStatus.NODE_FILTER_NOT_FOUND);
+        }
+        return Either.left(Boolean.TRUE);
+    }
+
+    private Either<Boolean, ResponseFormat> getErrorResponse(ActionStatus actionStatus, String... variables) {
+        ResponseFormat errorResponse = ResponseFormatManager.getInstance().getResponseFormat(actionStatus, variables);
+        return Either.right(errorResponse);
+    }
+
+    public Either<Boolean, ResponseFormat> validateNodeFilter(CINodeFilterDataDefinition nodeFilter, String serviceId,
+            String complonentInstanceId) {
+        return Either.left(Boolean.TRUE);
+    }
+
+
+    public Either<Boolean, ResponseFormat> validateNodeFilter(Service parentComponent, String componentInstanceId,
+            List<String> uiConstraints, NodeFilterConstraintAction action) {
+        try {
+            for (String uiConstraint : uiConstraints) {
+                if (NodeFilterConstraintAction.ADD != action && NodeFilterConstraintAction.UPDATE != action) {
+                    break;
+                }
+                UIConstraint constraint = new ConstraintConvertor().convert(uiConstraint);
+                if (ConstraintConvertor.PROPERTY_CONSTRAINT.equals(constraint.getSourceType())) {
+                    final Either<Boolean, ResponseFormat> booleanResponseFormatEither =
+                            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);
+                    if (booleanResponseFormatEither.isRight()) {
+                        return booleanResponseFormatEither;
+                    }
+                }
+            }
+        } catch (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> validatePropertyConstraint(Service parentComponent,
+            String componentInstanceId, UIConstraint uiConstraint) {
+        String source = SOURCE;
+        Optional<ComponentInstance> brotherComponentInstance;
+
+        List<? extends PropertyDefinition> sourcePropertyDefinition =
+                parentComponent.getName().equals(uiConstraint.getSourceName()) ? parentComponent.getProperties() :
+                        Collections.emptyList();
+
+
+        if (sourcePropertyDefinition.isEmpty() && !parentComponent.getName().equals(uiConstraint.getSourceName())) {
+            brotherComponentInstance = parentComponent.getComponentInstances().stream()
+                                                      .filter(componentInstance -> uiConstraint.getSourceName()
+                                                                                               .equals(componentInstance
+                                                                                                               .getName()))
+                                                      .findFirst();
+
+            if (brotherComponentInstance.isPresent()) {
+                final List<ComponentInstanceProperty> componentInstanceProperties =
+                        parentComponent.getComponentInstancesProperties()
+                                       .get(brotherComponentInstance.get().getUniqueId());
+                sourcePropertyDefinition =
+                        componentInstanceProperties == null ? new ArrayList<>() : componentInstanceProperties;
+            }
+        }
+
+        if (!CollectionUtils.isEmpty(sourcePropertyDefinition)) {
+            Optional<? extends PropertyDefinition> sourceSelectedProperty = sourcePropertyDefinition.stream()
+                                                                                                    .filter(property -> uiConstraint
+                                                                                                                                .getValue()
+                                                                                                                                .equals(property.getName()))
+                                                                                                    .findFirst();
+
+            Optional<? extends PropertyDefinition> targetComponentInstanceProperty =
+                    parentComponent.getComponentInstancesProperties().get(componentInstanceId).stream()
+                                   .filter(property -> uiConstraint.getServicePropertyName().equals(property.getName()))
+                                   .findFirst();
+
+            source = !targetComponentInstanceProperty.isPresent() ? "Target" : SOURCE;
+            if (sourceSelectedProperty.isPresent() && targetComponentInstanceProperty.isPresent()) {
+                return validatePropertyData(uiConstraint, sourceSelectedProperty, targetComponentInstanceProperty);
+            }
+        }
+
+        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> validatePropertyData(UIConstraint uiConstraint,
+            Optional<? extends PropertyDefinition> sourceSelectedProperty,
+            Optional<? extends PropertyDefinition> targetComponentInstanceProperty) {
+        final PropertyDefinition sourcePropDefinition = sourceSelectedProperty.get();
+        final String sourceType = sourcePropDefinition.getType();
+        final PropertyDefinition targetPropDefinition = targetComponentInstanceProperty.get();
+        final String targetType = targetPropDefinition.getType();
+        if (sourceType.equals(targetType)) {
+            if (schemableTypes.contains(sourceType)) {
+                final SchemaDefinition sourceSchemaDefinition = sourcePropDefinition.getSchema();
+                final SchemaDefinition targetSchemaDefinition = targetPropDefinition.getSchema();
+                if (!sourceSchemaDefinition.equals(targetSchemaDefinition)) {
+                    return Either.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()));
+        }
+    }
+
+    private Either<Boolean, ResponseFormat> validateStaticValueAndOperator(Service parentComponent,
+            String componentInstanceId, UIConstraint uiConstraint) {
+        if (!(Objects.nonNull(uiConstraint) && uiConstraint.getValue() instanceof String)) {
+            return Either.left(false);
+        }
+        Optional<ComponentInstanceProperty> componentInstanceProperty =
+                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()));
+        }
+        if (comparableConstraintsOperators.contains(uiConstraint.getConstraintOperator()) && !comparableTypes.contains(
+                componentInstanceProperty.get().getType())) {
+            return Either.right(componentsUtils.getResponseFormat(ActionStatus.UNSUPPORTED_OPERATOR_PROVIDED,
+                    uiConstraint.getServicePropertyName(), uiConstraint.getConstraintOperator()));
+        }
+
+        return isValidValueCheck(componentInstanceProperty.get().getType(), String.valueOf(uiConstraint.getValue()),
+                uiConstraint.getServicePropertyName());
+    }
+
+    private Either<Boolean, ResponseFormat> isValidValueCheck(String type, String value, String propertyName) {
+
+        ToscaPropertyType toscaPropertyType = ToscaPropertyType.isValidType(type);
+        if (Objects.isNull(toscaPropertyType)) {
+            return Either.right(
+                    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));
+    }
+
+
+}
+
+
diff --git a/catalog-be/src/main/java/org/openecomp/sdc/be/datamodel/utils/ConstraintConvertor.java b/catalog-be/src/main/java/org/openecomp/sdc/be/datamodel/utils/ConstraintConvertor.java
new file mode 100644 (file)
index 0000000..e05ef92
--- /dev/null
@@ -0,0 +1,138 @@
+package org.openecomp.sdc.be.datamodel.utils;
+
+import com.google.common.collect.ImmutableMap;
+import com.google.common.collect.ImmutableSet;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+import org.openecomp.sdc.be.model.tosca.constraints.ConstraintType;
+import org.openecomp.sdc.be.ui.model.UIConstraint;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.yaml.snakeyaml.Yaml;
+
+public class ConstraintConvertor {
+
+    private static final Logger logger = LoggerFactory.getLogger(ConstraintConvertor.class);
+
+    public static final String EQUAL_OPERATOR = ConstraintType.EQUAL.getTypes().get(1);
+    public static final String GREATER_THAN_OPERATOR = ConstraintType.GREATER_THAN.getTypes().get(1);
+    public static final String LESS_THAN_OPERATOR = ConstraintType.LESS_THAN.getTypes().get(1);
+    public static final String STATIC_CONSTRAINT = "static";
+    public static final String PROPERTY_CONSTRAINT = "property";
+    public static final String SERVICE_INPUT_CONSTRAINT = "service_input";
+    public static final String SELF = "SELF";
+    private static final Set<String> SUPPORTED_CONSTRAINT_LIST =
+            ImmutableSet.of(EQUAL_OPERATOR, GREATER_THAN_OPERATOR, LESS_THAN_OPERATOR);
+    private static final String GET_INPUT = "get_input";
+    private static final String GET_PROPERTY = "get_property";
+    private static final Set<String> SUPPORTED_FUNCTIONS = ImmutableSet.of(GET_INPUT, GET_PROPERTY);
+
+
+    public UIConstraint convert(String inConstraint) {
+        Yaml yamlSource = new Yaml();
+        UIConstraint uiConstraint = new UIConstraint();
+        Object content1 = yamlSource.load(inConstraint);
+        if (content1 instanceof Map) {
+            Map map1 = (Map) content1;
+            Object key = map1.keySet().iterator().next();
+            uiConstraint.setServicePropertyName(key.toString());
+            Object content2 = map1.get(key);
+            if (content2 instanceof Map && handleServiceConstraint(uiConstraint, (Map) content2)) {
+                return uiConstraint;
+            }
+        }
+        return null;
+    }
+
+    private boolean handleServiceConstraint(UIConstraint uiConstraint, Map content2) {
+        Map map2 = content2;
+        Object key2 = map2.keySet().iterator().next();
+        final String operator = key2.toString();
+        if (SUPPORTED_CONSTRAINT_LIST.contains(operator)) {
+            uiConstraint.setConstraintOperator(operator);
+        }
+        Object content3 = map2.get(key2);
+        if (content3 instanceof String || content3 instanceof Number || content3 instanceof Boolean) {
+            uiConstraint.setValue(content3);
+            uiConstraint.setSourceType(STATIC_CONSTRAINT);
+            return true;
+        } else if (content3 instanceof List) {
+            List list1 = (List) content3;
+            uiConstraint.setSourceType(STATIC_CONSTRAINT);
+            uiConstraint.setValue(list1);
+            return true;
+        } else if (content3 instanceof Map) {
+            Map map3 = (Map) content3;
+            Map.Entry entry = (Map.Entry) map3.entrySet().iterator().next();
+            final String firstKey = entry.getKey().toString().trim();
+            if (handleSupportedFunctions(uiConstraint, entry, firstKey)) {
+                return true;
+            }
+            uiConstraint.setValue(content3);
+            return true;
+        }
+        return false;
+    }
+
+    private boolean handleSupportedFunctions(UIConstraint uiConstraint, Map.Entry entry, String firstKey) {
+        if (SUPPORTED_FUNCTIONS.contains(firstKey)) {
+            if (GET_INPUT.equals(firstKey)) {
+                uiConstraint.setSourceType(SERVICE_INPUT_CONSTRAINT);
+                uiConstraint.setValue(entry.getValue());
+                return true;
+            } else if (GET_PROPERTY.equals(firstKey)) {
+                uiConstraint.setSourceType(PROPERTY_CONSTRAINT);
+                final List<String> value = (List<String>) entry.getValue();
+                uiConstraint.setSourceName(value.get(0));
+                uiConstraint.setValue(value.get(1));
+                return true;
+            }
+        }
+        return false;
+    }
+
+    public List<String> convertToList(List<UIConstraint> uiConstraints) {
+        List<String> retVal = new ArrayList<>();
+        for (UIConstraint uiConstraint : uiConstraints) {
+            String constraint = convert(uiConstraint);
+            if (constraint != null) {
+                retVal.add(constraint);
+            }
+        }
+        return retVal;
+    }
+
+    public String convert(UIConstraint uiConstraint) {
+        try {
+            Map map1 = new HashMap();
+            Map map2 = new HashMap();
+
+            map1.put(uiConstraint.getServicePropertyName(), map2);
+            if (uiConstraint.getSourceType().equals(STATIC_CONSTRAINT)) {
+                Object value = uiConstraint.getValue();
+                if (value instanceof String) {
+                    value = new Yaml().load(value.toString());
+                }
+                map2.put(uiConstraint.getConstraintOperator(), value);
+            } else if (uiConstraint.getSourceType().equals(PROPERTY_CONSTRAINT)) {
+                List list1 = Arrays.asList(uiConstraint.getSourceName(), uiConstraint.getValue());
+                Map map3 = ImmutableMap.of(GET_PROPERTY, list1);
+                map2.put(uiConstraint.getConstraintOperator(), map3);
+            } else if (uiConstraint.getSourceType().equals(SERVICE_INPUT_CONSTRAINT)) {
+                Map map3 = ImmutableMap.of(GET_INPUT, uiConstraint.getValue());
+                map2.put(uiConstraint.getConstraintOperator(), map3);
+            }
+
+
+            Yaml yamlSource = new Yaml();
+            return yamlSource.dump(map1);
+        } catch (NullPointerException ex) {
+            logger.error(ex.getMessage(), ex);
+        }
+        return null;
+    }
+}
diff --git a/catalog-be/src/main/java/org/openecomp/sdc/be/servlets/ServiceFilterServlet.java b/catalog-be/src/main/java/org/openecomp/sdc/be/servlets/ServiceFilterServlet.java
new file mode 100644 (file)
index 0000000..3daca3f
--- /dev/null
@@ -0,0 +1,258 @@
+package org.openecomp.sdc.be.servlets;
+
+import fj.data.Either;
+import io.swagger.annotations.Api;
+import io.swagger.annotations.ApiOperation;
+import io.swagger.annotations.ApiParam;
+import io.swagger.annotations.ApiResponse;
+import io.swagger.annotations.ApiResponses;
+import java.util.List;
+import java.util.Map;
+import java.util.stream.Collectors;
+import javax.inject.Singleton;
+import javax.servlet.ServletContext;
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpSession;
+import javax.ws.rs.Consumes;
+import javax.ws.rs.DELETE;
+import javax.ws.rs.HeaderParam;
+import javax.ws.rs.POST;
+import javax.ws.rs.PUT;
+import javax.ws.rs.Path;
+import javax.ws.rs.PathParam;
+import javax.ws.rs.Produces;
+import javax.ws.rs.core.Context;
+import javax.ws.rs.core.MediaType;
+import javax.ws.rs.core.Response;
+import org.codehaus.jackson.map.ObjectMapper;
+import org.openecomp.sdc.be.components.impl.ServiceBusinessLogic;
+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.CINodeFilterDataDefinition;
+import org.openecomp.sdc.be.datatypes.enums.ComponentTypeEnum;
+import org.openecomp.sdc.be.model.User;
+import org.openecomp.sdc.be.resources.data.auditing.AuditingActionEnum;
+import org.openecomp.sdc.be.tosca.utils.NodeFilterConverter;
+import org.openecomp.sdc.be.ui.model.UIConstraint;
+import org.openecomp.sdc.be.ui.model.UINodeFilter;
+import org.openecomp.sdc.common.api.Constants;
+import org.openecomp.sdc.exception.ResponseFormat;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+@Path("/v1/catalog/services/{serviceId}/resourceInstances/{resourceInstanceId}/nodeFilter")
+@Consumes(MediaType.APPLICATION_JSON)
+@Produces(MediaType.APPLICATION_JSON)
+@Api(value = "Service Filter", description = "Service Filter Servlet")
+@Singleton
+public class ServiceFilterServlet extends AbstractValidationsServlet {
+
+    private static final Logger log = LoggerFactory.getLogger(ServiceFilterServlet.class);
+    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_UPDATE_OR_CREATE_NODE_FILTER = "failed to update or create node filter";
+    private static final String FAILED_TO_PARSE_SERVICE = "failed to parse service";
+    private static final String NODE_FILTER_CREATION_OR_UPDATE = "Node Filter Creation or update";
+    private static final String CREATE_OR_UPDATE_NODE_FILTER_WITH_AN_ERROR =
+            "create or update node filter with an error";
+
+    @POST
+    @Consumes(MediaType.APPLICATION_JSON)
+    @Produces(MediaType.APPLICATION_JSON)
+    @Path("/")
+    @ApiOperation(value = "Add Service Filter Constraint", httpMethod = "POST", notes = "Add Service Filter Constraint",
+            response = Response.class)
+    @ApiResponses(value = {@ApiResponse(code = 201, message = "Create Service Filter"),
+            @ApiResponse(code = 403, message = "Restricted operation"),
+            @ApiResponse(code = 400, message = "Invalid content / Missing content")})
+    public Response addServiceFilterConstraint(@ApiParam(value = "Service data", required = true) String data,
+            @ApiParam(value = "Service Id") @PathParam("serviceId") String serviceId,
+            @ApiParam(value = "Resource Instance Id") @PathParam("resourceInstanceId") String ciId,
+            @Context final HttpServletRequest request, @HeaderParam(value = Constants.USER_ID_HEADER) String userId) {
+
+        String url = request.getMethod() + " " + request.getRequestURI();
+        log.debug(START_HANDLE_REQUEST_OF, url);
+        final HttpSession session = request.getSession();
+        ServletContext context = session.getServletContext();
+        User modifier = new User();
+        modifier.setUserId(userId);
+        log.debug(MODIFIER_ID_IS, userId);
+
+        Response response;
+
+        try {
+            String serviceIdLower = serviceId.toLowerCase();
+            ServiceBusinessLogic businessLogic = getServiceBL(context);
+
+            Either<UIConstraint, ResponseFormat> convertResponse = parseToConstraint(data, modifier);
+            if (convertResponse.isRight()) {
+                log.debug(FAILED_TO_PARSE_SERVICE);
+                response = buildErrorResponse(convertResponse.right().value());
+                return response;
+            }
+            UIConstraint uiConstraint = convertResponse.left().value();
+            if (uiConstraint == null) {
+                log.debug(FAILED_TO_PARSE_SERVICE);
+                response = buildErrorResponse(convertResponse.right().value());
+                return response;
+            }
+            Either<CINodeFilterDataDefinition, ResponseFormat> actionResponse;
+            String constraint = new ConstraintConvertor().convert(uiConstraint);
+            actionResponse = businessLogic
+                                     .addOrDeleteServiceFilter(serviceIdLower, ciId, NodeFilterConstraintAction.ADD,
+                                             constraint, -1, modifier, true);
+
+            if (actionResponse.isRight()) {
+                log.debug(FAILED_TO_UPDATE_OR_CREATE_NODE_FILTER);
+                response = buildErrorResponse(actionResponse.right().value());
+                return response;
+            }
+
+            CINodeFilterDataDefinition value = actionResponse.left().value();
+            UINodeFilter nodeFilter = new NodeFilterConverter().convertToUi(value);
+            return buildOkResponse(getComponentsUtils().getResponseFormat(ActionStatus.OK), nodeFilter);
+
+        } catch (Exception e) {
+            BeEcompErrorManager.getInstance().logBeRestApiGeneralError(NODE_FILTER_CREATION_OR_UPDATE);
+            log.debug(CREATE_OR_UPDATE_NODE_FILTER_WITH_AN_ERROR, e);
+            response = buildErrorResponse(getComponentsUtils().getResponseFormat(ActionStatus.GENERAL_ERROR));
+            return response;
+
+        }
+    }
+
+    @PUT
+    @Consumes(MediaType.APPLICATION_JSON)
+    @Produces(MediaType.APPLICATION_JSON)
+    @Path("/")
+    @ApiOperation(value = "Update Service Filter Constraint", httpMethod = "PUT",
+            notes = "Update Service Filter Constraint", response = Response.class)
+    @ApiResponses(value = {@ApiResponse(code = 201, message = "Create Service Filter"),
+            @ApiResponse(code = 403, message = "Restricted operation"),
+            @ApiResponse(code = 400, message = "Invalid content / Missing content")})
+    public Response updateServiceFilterConstraint(@ApiParam(value = "Service data", required = true) String data,
+            @ApiParam(value = "Service Id") @PathParam("serviceId") String serviceId,
+            @ApiParam(value = "Resource Instance Id") @PathParam("resourceInstanceId") String ciId,
+            @Context final HttpServletRequest request, @HeaderParam(value = Constants.USER_ID_HEADER) String userId) {
+        ServletContext context = request.getSession().getServletContext();
+        String url = request.getMethod() + " " + request.getRequestURI();
+        log.debug(START_HANDLE_REQUEST_OF, url);
+
+        User modifier = new User();
+        modifier.setUserId(userId);
+        log.debug(MODIFIER_ID_IS, userId);
+
+        Response response;
+
+        try {
+            String serviceIdLower = serviceId.toLowerCase();
+            ServiceBusinessLogic businessLogic = getServiceBL(context);
+
+            Either<List, ResponseFormat> convertResponse = parseToConstraints(data, modifier);
+            if (convertResponse.isRight()) {
+                log.debug(FAILED_TO_PARSE_SERVICE);
+                response = buildErrorResponse(convertResponse.right().value());
+                return response;
+            }
+            List<Map<String,String>> uiConstraintsMaps = (List<Map<String,String>>) convertResponse.left().value();
+            if (uiConstraintsMaps == null) {
+                log.debug("failed to parse data");
+                response = buildErrorResponse(convertResponse.right().value());
+                return response;
+            }
+            final ObjectMapper objectMapper = new ObjectMapper();
+            List<UIConstraint> uiConstraints = uiConstraintsMaps.stream().map(dataMap -> objectMapper.convertValue(dataMap, UIConstraint.class)).collect(
+                    Collectors.toList());
+            if (uiConstraints == null) {
+                log.debug("failed to parse data");
+                response = buildErrorResponse(convertResponse.right().value());
+                return response;
+            }
+            Either<CINodeFilterDataDefinition, ResponseFormat> actionResponse;
+            List<String> constraints = new ConstraintConvertor().convertToList(uiConstraints);
+            actionResponse = businessLogic.updateServiceFilter(serviceIdLower, ciId, constraints, modifier, true);
+
+            if (actionResponse.isRight()) {
+                log.debug(FAILED_TO_UPDATE_OR_CREATE_NODE_FILTER);
+                response = buildErrorResponse(actionResponse.right().value());
+                return response;
+            }
+
+            CINodeFilterDataDefinition value = actionResponse.left().value();
+            return buildOkResponse(getComponentsUtils().getResponseFormat(ActionStatus.OK),
+                    new NodeFilterConverter().convertToUi(value));
+
+        } catch (Exception e) {
+            BeEcompErrorManager.getInstance().logBeRestApiGeneralError(NODE_FILTER_CREATION_OR_UPDATE);
+            log.debug(CREATE_OR_UPDATE_NODE_FILTER_WITH_AN_ERROR, e);
+            response = buildErrorResponse(getComponentsUtils().getResponseFormat(ActionStatus.GENERAL_ERROR));
+            return response;
+
+        }
+    }
+
+    @DELETE
+    @Consumes(MediaType.APPLICATION_JSON)
+    @Produces(MediaType.APPLICATION_JSON)
+    @Path("/{constraintIndex}")
+    @ApiOperation(value = "Delete Service Filter Constraint", httpMethod = "Delete",
+            notes = "Delete Service Filter Constraint", response = Response.class)
+    @ApiResponses(value = {@ApiResponse(code = 201, message = "Delete Service Filter Constraint"),
+            @ApiResponse(code = 403, message = "Restricted operation"),
+            @ApiResponse(code = 400, message = "Invalid content / Missing content")})
+    public Response deleteServiceFilterConstraint(
+            @ApiParam(value = "Service Id") @PathParam("serviceId") String serviceId,
+            @ApiParam(value = "Resource Instance Id") @PathParam("resourceInstanceId") String ciId,
+            @ApiParam(value = "Constraint Index") @PathParam("constraintIndex") int index,
+            @Context final HttpServletRequest request, @HeaderParam(value = Constants.USER_ID_HEADER) String userId) {
+        ServletContext context = request.getSession().getServletContext();
+        String url = request.getMethod() + " " + request.getRequestURI();
+        log.debug(START_HANDLE_REQUEST_OF, url);
+
+        User modifier = new User();
+        modifier.setUserId(userId);
+        log.debug(MODIFIER_ID_IS, userId);
+
+        Response response;
+
+        try {
+            String serviceIdLower = serviceId.toLowerCase();
+            ServiceBusinessLogic businessLogic = getServiceBL(context);
+
+            Either<CINodeFilterDataDefinition, ResponseFormat> actionResponse;
+            actionResponse = businessLogic
+                                     .addOrDeleteServiceFilter(serviceIdLower, ciId, NodeFilterConstraintAction.DELETE,
+                                             null, index, modifier, true);
+
+            if (actionResponse.isRight()) {
+
+                log.debug(FAILED_TO_UPDATE_OR_CREATE_NODE_FILTER);
+                response = buildErrorResponse(actionResponse.right().value());
+                return response;
+            }
+
+            final CINodeFilterDataDefinition value = actionResponse.left().value();
+            return buildOkResponse(getComponentsUtils().getResponseFormat(ActionStatus.OK),
+                    new NodeFilterConverter().convertToUi(value));
+
+        } catch (Exception e) {
+            BeEcompErrorManager.getInstance().logBeRestApiGeneralError(NODE_FILTER_CREATION_OR_UPDATE);
+            log.debug(CREATE_OR_UPDATE_NODE_FILTER_WITH_AN_ERROR, e);
+            response = buildErrorResponse(getComponentsUtils().getResponseFormat(ActionStatus.GENERAL_ERROR));
+            return response;
+
+        }
+    }
+
+    private Either<UIConstraint, ResponseFormat> parseToConstraint(String serviceJson, User user) {
+        return getComponentsUtils().convertJsonToObjectUsingObjectMapper(serviceJson, user, UIConstraint.class,
+                AuditingActionEnum.CREATE_RESOURCE, ComponentTypeEnum.SERVICE);
+    }
+
+    private Either<List, ResponseFormat> parseToConstraints(String serviceJson, User user) {
+        return getComponentsUtils().convertJsonToObjectUsingObjectMapper(serviceJson, user, List.class,
+                AuditingActionEnum.CREATE_RESOURCE, ComponentTypeEnum.SERVICE);
+    }
+}
diff --git a/catalog-be/src/main/java/org/openecomp/sdc/be/tosca/model/CapabilityFilter.java b/catalog-be/src/main/java/org/openecomp/sdc/be/tosca/model/CapabilityFilter.java
new file mode 100644 (file)
index 0000000..58a9a75
--- /dev/null
@@ -0,0 +1,54 @@
+/*
+ * Copyright © 2016-2018 European Support Limited
+ *
+ * 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.
+ */
+
+package org.openecomp.sdc.be.tosca.model;
+
+
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Map;
+import org.apache.commons.collections.CollectionUtils;
+
+
+
+public class CapabilityFilter {
+
+    List<Map<String, List<Object>>> properties;
+
+    public List<Map<String, List<Object>>> getProperties() {
+        return properties;
+    }
+
+    public void setProperties(List<Map<String, List<Object>>> properties) {
+        this.properties = properties;
+    }
+
+    public void addProperty(Map<String, List<Object>> property) {
+        if(CollectionUtils.isEmpty(properties)) {
+            this.properties = new ArrayList<>();
+        }
+
+        this.properties.add(property);
+    }
+
+    @Override
+    public String toString() {
+        final StringBuilder sb = new StringBuilder("CapabilityFilter{");
+        sb.append("properties=").append(properties);
+        sb.append('}');
+        return sb.toString();
+    }
+}
diff --git a/catalog-be/src/main/java/org/openecomp/sdc/be/tosca/model/NodeFilter.java b/catalog-be/src/main/java/org/openecomp/sdc/be/tosca/model/NodeFilter.java
new file mode 100644 (file)
index 0000000..79e9f57
--- /dev/null
@@ -0,0 +1,50 @@
+/*
+ * Copyright © 2016-2018 European Support Limited
+ *
+ * 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.
+ */
+package org.openecomp.sdc.be.tosca.model;
+
+import java.util.List;
+import java.util.Map;
+
+public class NodeFilter {
+
+    Object tosca_id;
+    List<Map<String, List<Object>>> properties;
+    List<Map<String, CapabilityFilter>> capabilities;
+
+    public Object getTosca_id() {
+        return tosca_id;
+    }
+
+    public void setTosca_id(Object tosca_id) {
+        this.tosca_id = tosca_id;
+    }
+
+    public List<Map<String, CapabilityFilter>> getCapabilities() {
+        return capabilities;
+    }
+
+    public void setCapabilities(List<Map<String, CapabilityFilter>> capabilities) {
+        this.capabilities = capabilities;
+    }
+
+    public List<Map<String, List<Object>>> getProperties() {
+        return properties;
+    }
+
+    public void setProperties(List<Map<String, List<Object>>> properties) {
+        this.properties = properties;
+    }
+}
\ No newline at end of file
diff --git a/catalog-be/src/main/java/org/openecomp/sdc/be/tosca/utils/NodeFilterConverter.java b/catalog-be/src/main/java/org/openecomp/sdc/be/tosca/utils/NodeFilterConverter.java
new file mode 100644 (file)
index 0000000..af0837f
--- /dev/null
@@ -0,0 +1,139 @@
+/*
+ * Copyright © 2016-2018 European Support Limited
+ *
+ * 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.
+ */
+
+package org.openecomp.sdc.be.tosca.utils;
+
+import java.util.Collections;
+import java.util.HashMap;
+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.CINodeFilterDataDefinition;
+import org.openecomp.sdc.be.datatypes.elements.RequirementNodeFilterCapabilityDataDefinition;
+import org.openecomp.sdc.be.datatypes.elements.RequirementNodeFilterPropertyDataDefinition;
+import org.openecomp.sdc.be.tosca.model.CapabilityFilter;
+import org.openecomp.sdc.be.tosca.model.NodeFilter;
+import org.openecomp.sdc.be.ui.model.UIConstraint;
+import org.openecomp.sdc.be.ui.model.UINodeFilter;
+
+public class NodeFilterConverter {
+
+
+    public NodeFilter convertNodeFilter(CINodeFilterDataDefinition nodeFilterData) {
+        NodeFilter retVal = new NodeFilter();
+        if (nodeFilterData.getCapabilities() != null) {
+            retVal.setCapabilities(convertCapabilities(nodeFilterData.getCapabilities().getListToscaDataDefinition()));
+        }
+        if (nodeFilterData.getProperties() != null) {
+            retVal.setProperties(convertProperties(nodeFilterData.getProperties().getListToscaDataDefinition()));
+        }
+        return retVal;
+    }
+
+    private List<Map<String, CapabilityFilter>> convertCapabilities(
+            List<RequirementNodeFilterCapabilityDataDefinition> capabilities) {
+        if (CollectionUtils.isEmpty(capabilities)) {
+            return Collections.emptyList();
+        }
+        return capabilities.stream().map(this::transformCapability).collect(Collectors.toList());
+    }
+
+    private Map<String, CapabilityFilter> transformCapability(
+            RequirementNodeFilterCapabilityDataDefinition capability) {
+        Map<String, CapabilityFilter> retVal = new HashMap<>();
+        if (capability.getProperties() == null) {
+            return retVal;
+        }
+        List<RequirementNodeFilterPropertyDataDefinition> propertyDataDefinitionList =
+                capability.getProperties().getListToscaDataDefinition();
+        for (RequirementNodeFilterPropertyDataDefinition propertyDataDefinition : propertyDataDefinitionList) {
+            retVal.put(capability.getName(), convertCapabilityProperty(propertyDataDefinition));
+        }
+        return retVal;
+    }
+
+    private List<Map<String, List<Object>>> convertProperties(
+            List<RequirementNodeFilterPropertyDataDefinition> properties) {
+        if (CollectionUtils.isEmpty(properties)) {
+            return Collections.emptyList();
+        }
+        return properties.stream().map(this::transformProperty).collect(Collectors.toList());
+    }
+
+    private CapabilityFilter convertCapabilityProperty(RequirementNodeFilterPropertyDataDefinition property) {
+        TransformCapabilityData transformCapabilityData = new TransformCapabilityData(property).invoke();
+        Map<String, List<Object>> tranformedMap = transformCapabilityData.getRetVal();
+        List<Object> constraints = transformCapabilityData.getConstraints();
+        tranformedMap.put(property.getName(), constraints);
+        CapabilityFilter capabilityFilter = new CapabilityFilter();
+        capabilityFilter.setProperties(Collections.singletonList(tranformedMap));
+        return capabilityFilter;
+    }
+
+
+    private Map<String, List<Object>> transformProperty(RequirementNodeFilterPropertyDataDefinition property) {
+        TransformCapabilityData transformCapabilityData = new TransformCapabilityData(property).invoke();
+        Map<String, List<Object>> retVal = transformCapabilityData.getRetVal();
+        List<Object> constraints = transformCapabilityData.getConstraints();
+        retVal.put(property.getName(), constraints);
+
+        return retVal;
+    }
+
+    private class TransformCapabilityData {
+
+        private RequirementNodeFilterPropertyDataDefinition property;
+        private Map<String, List<Object>> retVal;
+        private List<Object> constraints;
+
+        public TransformCapabilityData(RequirementNodeFilterPropertyDataDefinition property) {
+            this.property = property;
+        }
+
+        public Map<String, List<Object>> getRetVal() {
+            return retVal;
+        }
+
+        public List<Object> getConstraints() {
+            return constraints;
+        }
+
+        public TransformCapabilityData invoke() {
+            final List<String> propertyConstraints = property.getConstraints();
+            if (CollectionUtils.isEmpty(propertyConstraints)) {
+                return this;
+            }
+            this.constraints = propertyConstraints.stream().map(c -> (Object) c).collect(Collectors.toList());
+            return this;
+        }
+    }
+
+    public UINodeFilter convertToUi(CINodeFilterDataDefinition inNodeFilter) {
+        UINodeFilter retVal = new UINodeFilter();
+        final ConstraintConvertor constraintConvertor = new ConstraintConvertor();
+        if (inNodeFilter.getProperties() == null || inNodeFilter.getProperties().isEmpty()) {
+            return retVal;
+        }
+        List<UIConstraint> constraints = inNodeFilter.getProperties().getListToscaDataDefinition().stream()
+                                                     .map(property -> property.getConstraints().iterator().next())
+                                                     .map(str -> constraintConvertor.convert(str))
+                                                     .collect(Collectors.toList());
+        retVal.setProperties(constraints);
+        return retVal;
+    }
+}
index 315027b..69f67e6 100644 (file)
@@ -2173,6 +2173,68 @@ errors:
         message: "Error: Invalid input, only pre-defined operation names are allowed in global interface type '%1'",
         messageId: "SVC4713"
     }
+
+    #---------SVC4714-----------------------------
+    NODE_FILTER_NOT_FOUND: {
+        code: 400,
+        message: "Error: Node Filter was not found",
+        messageId: "SVC4714"
+    }
+    #---------SVC4715----------------------------
+    UNSUPPORTED_VALUE_PROVIDED: {
+        code: 400,
+        message: "Error: Supported value type is %1 for %2 property. Provided Value: %3",
+        messageId: "SVC4715"
+    }
+    #---------SVC4716----------------------------
+    # %1 - Property Name
+    SELECTED_PROPERTY_NOT_PRESENT: {
+        code: 400,
+        message: "Error: %1 property does not exists in Service anymore.",
+        messageId: "SVC4716"
+    }
+
+    #---------SVC4717----------------------------
+    # %1 - Property Name
+    MAPPED_PROPERTY_NOT_FOUND: {
+        code: 400,
+        message: "Error: %1 property does not exist.",
+        messageId: "SVC4717"
+    }
+
+    #---------SVC4718----------------------------
+    # %1 - Property Name
+    # %2 - Operator Name
+    UNSUPPORTED_OPERATOR_PROVIDED: {
+        code: 400,
+        message: "Error: %1 property does not support %2 operator.",
+        messageId: "SVC4718"
+    }
+
+    #---------SVC4719----------------------------
+    CONSTRAINT_FORMAT_INCORRECT: {
+        code: 400,
+        message: "Error: Constraint provided does not contains expected values.",
+        messageId: "SVC4719"
+    }
+
+    #---------SVC4720----------------------------
+    # %1 - Property Name
+    # %2 - Operator Type
+    SOURCE_TARGET_PROPERTY_TYPE_MISMATCH: {
+        code: 400,
+        message: "Error: %1 property and %2 property type is not same.",
+        messageId: "SVC4720"
+    }
+
+    #---------SVC4721----------------------------
+    # %1 - Property Type
+    # %2 - Operator Type
+    UNSUPPORTED_PROPERTY_TYPE: {
+        code: 400,
+        message: "Error: Property type %1 provided against %2 is not supported for static value.",
+        messageId: "SVC4721"
+    }
 #---------SVC4714-----------------------------
 # %1 - Interface Operation output name
     INTERFACE_OPERATION_MAPPED_OUTPUT_DELETED: {
diff --git a/catalog-be/src/test/java/org/openecomp/sdc/be/components/validation/NodeFilterValidationTest.java b/catalog-be/src/test/java/org/openecomp/sdc/be/components/validation/NodeFilterValidationTest.java
new file mode 100644 (file)
index 0000000..fe9827f
--- /dev/null
@@ -0,0 +1,287 @@
+package org.openecomp.sdc.be.components.validation;
+
+import fj.data.Either;
+import java.util.Arrays;
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+import org.junit.Assert;
+import org.junit.Before;
+import org.junit.Test;
+import org.mockito.InjectMocks;
+import org.mockito.Mockito;
+import org.mockito.MockitoAnnotations;
+import org.openecomp.sdc.be.components.impl.utils.NodeFilterConstraintAction;
+import org.openecomp.sdc.be.dao.api.ActionStatus;
+import org.openecomp.sdc.be.datatypes.elements.PropertyDataDefinition;
+import org.openecomp.sdc.be.datatypes.elements.SchemaDefinition;
+import org.openecomp.sdc.be.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.exception.ResponseFormat;
+
+public class NodeFilterValidationTest {
+
+    private static final String UI_CONSTRAINT_STATIC = "Prop1: {equal: 'value'}";
+    private static final String INNER_SERVICE = "innerService";
+    private static final String PROPERTY_NAME = "Prop1";
+    private static final String VALUE = "value";
+    private static final String FLOAT_TYPE = "float";
+    private static final String STRING_TYPE = "string";
+    private static final String LIST_TYPE = "list";
+    private static final String COMPONENT1_ID = "component1";
+    private static final String INTEGER_TYPE = "integer";
+    private static final String PARENTSERVICE_ID = "parentservice";
+    private static final String COMPONENT2_ID = "component2";
+    private ComponentsUtils componentsUtils;
+
+    @InjectMocks
+    private NodeFilterValidator nodeFilterValidator;
+
+    @Before
+    public void setup() {
+        componentsUtils = Mockito.mock(ComponentsUtils.class);
+        MockitoAnnotations.initMocks(this);
+    }
+
+    @Test
+    public void testValidateNodeFilterStaticIncorrectPropertyTypeProvided() {
+        Service service = createService("booleanIncorrect");
+        Either<Boolean, ResponseFormat> either =
+                nodeFilterValidator.validateNodeFilter(service, INNER_SERVICE,
+                        Collections.singletonList(UI_CONSTRAINT_STATIC.replace(VALUE, "true")),
+                        NodeFilterConstraintAction.ADD);
+
+        Assert.assertFalse(either.isLeft());
+    }
+
+    @Test
+    public void testValidateNodeFilterStaticIncorrectOperatorProvidedBoolean() {
+        Service service = createService("boolean");
+        Either<Boolean, ResponseFormat> either =
+                nodeFilterValidator.validateNodeFilter(service, INNER_SERVICE,
+                        Collections.singletonList(UI_CONSTRAINT_STATIC.replace(VALUE, "true")
+                                .replace("equal", "greater_than")),
+                        NodeFilterConstraintAction.ADD);
+
+        Assert.assertFalse(either.isLeft());
+    }
+
+    @Test
+    public void testValidateNodeFilterStaticIncorrectValueProvidedBoolean() {
+        Service service = createService("boolean");
+        Either<Boolean, ResponseFormat> either =
+                nodeFilterValidator.validateNodeFilter(service, INNER_SERVICE,
+                        Collections.singletonList(UI_CONSTRAINT_STATIC.replace(VALUE, "trues")),
+                        NodeFilterConstraintAction.ADD);
+
+        Assert.assertFalse(either.isLeft());
+    }
+
+    @Test
+    public void testValidateNodeFilterStaticIncorrectOperatorProvidedString() {
+        Service service = createService(STRING_TYPE);
+        Either<Boolean, ResponseFormat> either =
+                nodeFilterValidator.validateNodeFilter(service, INNER_SERVICE,
+                        Collections.singletonList(UI_CONSTRAINT_STATIC.replace(VALUE, "true")
+                                .replace("equal", "greater_than")),
+                        NodeFilterConstraintAction.ADD);
+
+        Assert.assertTrue(either.isLeft());
+    }
+
+    @Test
+    public void testValidateNodeFilterIntegerValueSuccess() {
+        Service service = createService(INTEGER_TYPE);
+        Either<Boolean, ResponseFormat> either =
+                nodeFilterValidator.validateNodeFilter(service, INNER_SERVICE,
+                        Collections.singletonList(UI_CONSTRAINT_STATIC.replace(VALUE, "1")),
+                                NodeFilterConstraintAction.ADD);
+
+        Assert.assertTrue(either.isLeft());
+    }
+
+    @Test
+    public void testValidateNodeFilterIntegerValueFail() {
+        Service service = createService(INTEGER_TYPE);
+
+        Mockito.when(componentsUtils.getResponseFormat(ActionStatus.UNSUPPORTED_VALUE_PROVIDED, "param1"))
+                .thenReturn(new ResponseFormat());
+
+        Either<Boolean, ResponseFormat> either =
+                nodeFilterValidator.validateNodeFilter(service, INNER_SERVICE,
+                        Collections.singletonList(UI_CONSTRAINT_STATIC.replace(VALUE, "1.0")),
+                        NodeFilterConstraintAction.ADD);
+
+        Assert.assertTrue(either.isRight());
+    }
+
+    @Test
+    public void testValidateNodeFilterFloatValueSuccess() {
+        Service service = createService(FLOAT_TYPE);
+        Either<Boolean, ResponseFormat> either =
+                nodeFilterValidator.validateNodeFilter(service, INNER_SERVICE,
+                        Collections.singletonList(UI_CONSTRAINT_STATIC.replace(VALUE, "1.0")),
+                        NodeFilterConstraintAction.ADD);
+
+        Assert.assertTrue(either.isLeft());
+    }
+
+    @Test
+    public void testValidateNodeFilterFloatValueFail() {
+        Service service = createService(FLOAT_TYPE);
+
+        Mockito.when(componentsUtils.getResponseFormat(ActionStatus.UNSUPPORTED_VALUE_PROVIDED, "param1"))
+                .thenReturn(new ResponseFormat());
+
+        Either<Boolean, ResponseFormat> either =
+                nodeFilterValidator.validateNodeFilter(service, INNER_SERVICE,
+                        Collections.singletonList(UI_CONSTRAINT_STATIC), NodeFilterConstraintAction.ADD);
+
+        Assert.assertTrue(either.isRight());
+    }
+
+    @Test
+    public void testValidateNodeFilterStringValueSuccess() {
+        Service service = createService(STRING_TYPE);
+        Either<Boolean, ResponseFormat> either =
+                nodeFilterValidator.validateNodeFilter(service, INNER_SERVICE,
+                        Collections.singletonList(UI_CONSTRAINT_STATIC), NodeFilterConstraintAction.ADD);
+
+        Assert.assertTrue(either.isLeft());
+    }
+
+    @Test
+    public void testValidatePropertyConstraintBrotherSuccess() {
+        Service service = createService(STRING_TYPE);
+        Either<Boolean, ResponseFormat> either =
+                nodeFilterValidator.validateNodeFilter(service, COMPONENT1_ID, Collections.singletonList("Prop1:\n"
+                        + "  equal:  { get_property :[component2, Prop1]}\n"), NodeFilterConstraintAction.ADD);
+
+        Assert.assertTrue(either.isLeft());
+    }
+
+    @Test
+    public void testValidatePropertyConstraintParentSuccess() {
+        Service service = createService(STRING_TYPE);
+        Either<Boolean, ResponseFormat> either =
+                nodeFilterValidator.validateNodeFilter(service, COMPONENT1_ID, Collections.singletonList("Prop1:\n"
+                        + "  equal:  { get_property : [parentservice, Prop1]}\n"), NodeFilterConstraintAction.ADD);
+
+        Assert.assertTrue(either.isLeft());
+    }
+
+    @Test
+    public void testValidatePropertyConstraintBrotherPropertyTypeMismatch() {
+        Service service = createService(STRING_TYPE);
+        service.getComponentInstancesProperties().get(COMPONENT2_ID).get(0).setType(INTEGER_TYPE);
+
+        Either<Boolean, ResponseFormat> either =
+                nodeFilterValidator.validateNodeFilter(service, COMPONENT1_ID, Collections.singletonList("Prop1:\n"
+                        + "  equal: { get_property : [component2, Prop1]}\n"), NodeFilterConstraintAction.ADD);
+
+        Assert.assertFalse(either.isLeft());
+    }
+
+    @Test
+    public void testValidatePropertyConstraintParentPropertyTypeMismatch() {
+        Service service = createService(STRING_TYPE);
+        service.getComponentInstancesProperties().get(COMPONENT1_ID).get(0).setType(INTEGER_TYPE);
+
+        Either<Boolean, ResponseFormat> either =
+                nodeFilterValidator.validateNodeFilter(service, COMPONENT1_ID, Collections.singletonList("Prop1:\n"
+                        + "  equal: { get_property : [parentservice, Prop1]}\n"), NodeFilterConstraintAction.ADD);
+
+        Assert.assertFalse(either.isLeft());
+    }
+
+    @Test
+    public void testValidatePropertyConstraintParentPropertyNotFound() {
+        Service service = createService(STRING_TYPE);
+        service.getComponentInstancesProperties().get(COMPONENT1_ID).get(0).setName("Prop2");
+
+        Either<Boolean, ResponseFormat> either =
+                nodeFilterValidator.validateNodeFilter(service, COMPONENT1_ID, Collections.singletonList("Prop1:\n"
+                        + "  equal: { get_property : [parentservice, Prop1]}\n"), NodeFilterConstraintAction.ADD);
+
+        Assert.assertFalse(either.isLeft());
+    }
+
+    @Test
+    public void testvalidatePropertyConstraintBrotherPropertyNotFound() {
+        Service service = createService(STRING_TYPE);
+        service.getComponentInstancesProperties().get(COMPONENT1_ID).get(0).setName("Prop2");
+
+        Either<Boolean, ResponseFormat> either =
+                nodeFilterValidator.validateNodeFilter(service, COMPONENT1_ID, Collections.singletonList("Prop1:\n"
+                        + "  equal:  { get_property : [parentservice, Prop1]}\n"), NodeFilterConstraintAction.ADD);
+
+        Assert.assertFalse(either.isLeft());
+    }
+
+    @Test
+    public void testValidatePropertyConstraintParentPropertySchemaMismatch() {
+        Service service = createService(LIST_TYPE,STRING_TYPE);
+        service.getComponentInstancesProperties().get(COMPONENT1_ID).get(0).setType(LIST_TYPE);
+
+        Either<Boolean, ResponseFormat> either =
+                nodeFilterValidator.validateNodeFilter(service, COMPONENT1_ID, Collections.singletonList("Prop1:\n"
+                                                                                                                 + "  equal: { get_property : [parentservice, Prop1]}\n"), NodeFilterConstraintAction.ADD);
+
+        Assert.assertFalse(either.isLeft());
+    }
+
+    private Service createService(String type) {
+        return createService(type, null);
+    }
+
+    private Service createService(String type, String schemaType) {
+        Service service = new Service();
+        service.setName(PARENTSERVICE_ID);
+
+        PropertyDefinition propertyDefinition = new PropertyDefinition();
+        propertyDefinition.setName(PROPERTY_NAME);
+        propertyDefinition.setType(type);
+        if (schemaType != null){
+            SchemaDefinition schemaDefinition = new SchemaDefinition();
+            PropertyDataDefinition schemaProperty = new PropertyDataDefinition();
+            schemaProperty.setType(schemaType);
+            schemaDefinition.setProperty(schemaProperty);
+            propertyDefinition.setSchema(schemaDefinition);
+        }
+        service.setProperties(Collections.singletonList(propertyDefinition));
+
+        ComponentInstance componentInstance = new ComponentInstance();
+        componentInstance.setUniqueId(COMPONENT1_ID);
+        componentInstance.setName(COMPONENT1_ID);
+
+        ComponentInstance componentInstance2 = new ComponentInstance();
+        componentInstance2.setUniqueId(COMPONENT2_ID);
+        componentInstance2.setName(COMPONENT2_ID);
+
+        service.setComponentInstances(Arrays.asList(componentInstance, componentInstance2));
+
+        ComponentInstanceProperty componentInstanceProperty  = new ComponentInstanceProperty();
+        componentInstanceProperty.setName(PROPERTY_NAME);
+        componentInstanceProperty.setType(type);
+
+        ComponentInstanceProperty componentInstanceProperty2  = new ComponentInstanceProperty();
+        componentInstanceProperty2.setName(PROPERTY_NAME);
+        componentInstanceProperty2.setType(type);
+
+        Map<String, List<ComponentInstanceProperty>> componentInstancePropertyMap = new HashMap<>();
+        componentInstancePropertyMap.put(componentInstance.getUniqueId(),
+                Collections.singletonList(componentInstanceProperty));
+        componentInstancePropertyMap.put(componentInstance2.getUniqueId(),
+                Collections.singletonList(componentInstanceProperty2));
+        componentInstancePropertyMap.put(INNER_SERVICE, Collections.singletonList(componentInstanceProperty));
+
+        service.setComponentInstancesProperties(componentInstancePropertyMap);
+
+        return service;
+    }
+
+}
\ No newline at end of file
diff --git a/catalog-be/src/test/java/org/openecomp/sdc/be/tosca/model/ConstraintConvertorTest.java b/catalog-be/src/test/java/org/openecomp/sdc/be/tosca/model/ConstraintConvertorTest.java
new file mode 100644 (file)
index 0000000..942a279
--- /dev/null
@@ -0,0 +1,176 @@
+/*
+ * Copyright © 2016-2018 European Support Limited
+ *
+ * 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.
+ */
+package org.openecomp.sdc.be.tosca.model;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertNotNull;
+import static org.junit.Assert.assertTrue;
+
+import java.util.List;
+import java.util.Map;
+import org.junit.Test;
+import org.openecomp.sdc.be.datamodel.utils.ConstraintConvertor;
+import org.openecomp.sdc.be.ui.model.UIConstraint;
+
+public class ConstraintConvertorTest {
+
+    @Test
+    public void convertStatic(){
+        ConstraintConvertor constraintConvertor = new ConstraintConvertor();
+        UIConstraint uiConstraint = constraintConvertor.convert("mem_size: {equal: some static}\n");
+        assertNotNull(uiConstraint);
+        assertEquals(uiConstraint.getConstraintOperator(),"equal");
+        assertEquals(uiConstraint.getValue(),"some static");
+        assertEquals(uiConstraint.getServicePropertyName().trim(),"mem_size");
+    }
+
+    @Test
+    public void convertFromStatic(){
+        ConstraintConvertor constraintConvertor = new ConstraintConvertor();
+        UIConstraint uiConstraint = new UIConstraint("mem_size", "equal" , ConstraintConvertor.STATIC_CONSTRAINT, "some static");
+        String constraint  = constraintConvertor.convert(uiConstraint);
+        assertNotNull(constraint);
+        assertEquals("mem_size: {equal: some static}\n", constraint);
+    }
+
+    @Test
+    public void convertSelfProperty(){
+        ConstraintConvertor constraintConvertor = new ConstraintConvertor();
+        UIConstraint uiConstraint = constraintConvertor.convert("mem_size:\n {equal: { get_property: [SELF, size] }}");
+        assertNotNull(uiConstraint);
+        assertEquals(uiConstraint.getConstraintOperator(),"equal");
+        assertEquals(uiConstraint.getValue(),"size");
+        assertEquals(uiConstraint.getServicePropertyName().trim(),"mem_size");
+        assertEquals(uiConstraint.getSourceName().trim(),"SELF");
+        assertEquals(uiConstraint.getSourceType(), ConstraintConvertor.PROPERTY_CONSTRAINT);
+    }
+
+    @Test
+    public void convertFromSelfProperty(){
+        ConstraintConvertor constraintConvertor = new ConstraintConvertor();
+        UIConstraint uiConstraint = new UIConstraint("mem_size", "equal" , ConstraintConvertor.PROPERTY_CONSTRAINT, "SELF" ,"some static");
+        String constraint  = constraintConvertor.convert(uiConstraint);
+        assertNotNull(constraint);
+        assertEquals("mem_size:\n" + "  equal:\n" + "    get_property: [SELF, some static]\n", constraint);
+    }
+
+    @Test
+    public void convertCIProperty(){
+        ConstraintConvertor constraintConvertor = new ConstraintConvertor();
+        UIConstraint uiConstraint = constraintConvertor.convert("mem_size:\n" + "  equal: { get_property: [A, size]}");
+        assertNotNull(uiConstraint);
+        assertEquals(uiConstraint.getConstraintOperator(),"equal");
+        assertEquals(uiConstraint.getValue(),"size");
+        assertEquals(uiConstraint.getServicePropertyName().trim(),"mem_size");
+        assertEquals(uiConstraint.getSourceName().trim(),"A");
+    }
+
+
+    @Test
+    public void convertFromCIProperty(){
+        ConstraintConvertor constraintConvertor = new ConstraintConvertor();
+        UIConstraint uiConstraint = new UIConstraint("mem_size", "equal" , ConstraintConvertor.PROPERTY_CONSTRAINT, "A" ,"size");
+        String constraint  = constraintConvertor.convert(uiConstraint);
+        assertNotNull(constraint);
+        assertEquals("mem_size:\n" + "  equal:\n" + "    get_property: [A, size]\n", constraint);
+    }
+
+    @Test
+    public void convertServiceTemplateInput(){
+        ConstraintConvertor constraintConvertor = new ConstraintConvertor();
+        UIConstraint uiConstraint = constraintConvertor.convert("mem_size: {equal: {get_input: InputName}}\n");
+        assertNotNull(uiConstraint);
+    }
+
+    @Test
+    public void convertFromServiceTemplateInput(){
+        ConstraintConvertor constraintConvertor = new ConstraintConvertor();
+        UIConstraint uiConstraint = new UIConstraint("mem_size", "equal" , ConstraintConvertor.SERVICE_INPUT_CONSTRAINT, "InputName");
+        String constraint  = constraintConvertor.convert(uiConstraint);
+        assertNotNull(constraint);
+        assertEquals("mem_size:\n  equal: {get_input: InputName}\n", constraint);
+    }
+
+    @Test
+    public void convertGreaterThanStatic(){
+        ConstraintConvertor constraintConvertor = new ConstraintConvertor();
+        UIConstraint uiConstraint = constraintConvertor.convert("mem_size: {greater_than: 2}\n");
+        assertNotNull(uiConstraint);
+        assertEquals(uiConstraint.getConstraintOperator(),"greater_than");
+        assertEquals(uiConstraint.getValue(),2);
+        assertEquals(uiConstraint.getServicePropertyName().trim(),"mem_size");
+    }
+
+    @Test
+    public void convertFromGreaterThanStatic(){
+        ConstraintConvertor constraintConvertor = new ConstraintConvertor();
+        UIConstraint uiConstraint = new UIConstraint("mem_size", "greater_than" , ConstraintConvertor.STATIC_CONSTRAINT, 2);
+        String constraint  = constraintConvertor.convert(uiConstraint);
+        assertNotNull(constraint);
+        assertEquals("mem_size: {greater_than: 2}\n", constraint);
+    }
+
+    @Test
+    public void convertLessThanServiceProperty(){
+        ConstraintConvertor constraintConvertor = new ConstraintConvertor();
+        UIConstraint uiConstraint = constraintConvertor.convert("mem_size: {less_then: {get_input: InputName}}");
+        assertNotNull(uiConstraint);
+    }
+
+    @Test
+    public void convertFromLessThanServiceProperty(){
+        ConstraintConvertor constraintConvertor = new ConstraintConvertor();
+        UIConstraint uiConstraint = new UIConstraint("mem_size", "less_then" , ConstraintConvertor.SERVICE_INPUT_CONSTRAINT, "InputName");
+        String constraint  = constraintConvertor.convert(uiConstraint);
+        assertNotNull(constraint);
+        assertEquals("mem_size:\n" + "  less_then: {get_input: InputName}\n", constraint);
+    }
+
+    @Test
+    public void convertFromEqualStaticMap(){
+        ConstraintConvertor constraintConvertor = new ConstraintConvertor();
+        UIConstraint uiConstraint = new UIConstraint("mem_size", "equal" , ConstraintConvertor.STATIC_CONSTRAINT, "{x: xx,"+
+                                                                                                                          " y: yy}\n");
+        String constraint  = constraintConvertor.convert(uiConstraint);
+        assertNotNull(constraint);
+        assertEquals("mem_size:\n" + "  equal: {x: xx, y: yy}\n", constraint);
+    }
+
+    @Test
+    public void convertStringToMap(){
+        ConstraintConvertor constraintConvertor = new ConstraintConvertor();
+        UIConstraint uiConstraint = constraintConvertor.convert("mem_size:\n" + "  equal: {x: xx, y: yy}\n");
+        assertNotNull(uiConstraint);
+        assertTrue(uiConstraint.getValue() instanceof Map);
+    }
+
+    @Test
+    public void convertFromEqualStaticList(){
+        ConstraintConvertor constraintConvertor = new ConstraintConvertor();
+        UIConstraint uiConstraint = new UIConstraint("mem_size", "equal" , ConstraintConvertor.STATIC_CONSTRAINT, "[x, y]\n");
+        String constraint  = constraintConvertor.convert(uiConstraint);
+        assertNotNull(constraint);
+        assertEquals("mem_size:\n" + "  equal: [x, y]\n", constraint);
+    }
+
+    @Test
+    public void convertStringToList(){
+        ConstraintConvertor constraintConvertor = new ConstraintConvertor();
+        UIConstraint uiConstraint = constraintConvertor.convert("mem_size:\n" + "  equal: [x, y]\n");
+        assertNotNull(uiConstraint);
+        assertTrue(uiConstraint.getValue() instanceof List);
+    }
+}
index fd6bace..8715e1d 100644 (file)
@@ -129,6 +129,18 @@ public enum ActionStatus {
     INTERFACE_OPERATION_INPUT_PROPERTY_NOT_FOUND_IN_COMPONENT, INTERFACE_OPERATION_INVALID_FOR_LOCAL_TYPE,
     INTERFACE_OPERATION_INVALID_FOR_GLOBAL_TYPE,
 
+    //NodeFilter
+    NODE_FILTER_NOT_FOUND,
+    UNSUPPORTED_VALUE_PROVIDED,
+    SELECTED_PROPERTY_NOT_PRESENT,
+    MAPPED_PROPERTY_NOT_FOUND,
+    UNSUPPORTED_OPERATOR_PROVIDED,
+    CONSTRAINT_FORMAT_INCORRECT,
+    SOURCE_TARGET_PROPERTY_TYPE_MISMATCH,
+    SOURCE_TARGET_SCHEMA_MISMATCH,
+    UNSUPPORTED_PROPERTY_TYPE,
+
+
     //InterfaceLifeCycleType
     INTERFACE_LIFECYCLE_TYPES_NOT_FOUND;
 }
index c7a2f2e..119888b 100644 (file)
@@ -63,7 +63,8 @@ public enum EdgeLabelEnum {
        PROXY_OF,
        ALLOTTED_OF,
        INTERFACE,
-       INTERFACE_OPERATION;
+       INTERFACE_OPERATION,
+       NODE_FILTER_TEMPLATE;
     
     /**
         * Returns EdgeLabelEnum according received name
index aa4de11..108d5e7 100644 (file)
@@ -60,7 +60,8 @@ public enum VertexTypeEnum {
        CATALOG_ROOT                ("catalogRoot",                 null),
        ARCHIVE_ROOT                ("archiveRoot",                 null),
        INTERFACE               ("interface",                   InterfaceDataDefinition.class),
-       INTERFACE_OPERATION                     ("interfaceOperation",                  OperationDataDefinition.class);
+       INTERFACE_OPERATION                     ("interfaceOperation",                  OperationDataDefinition.class),
+       NODE_FILTER_TEMPLATE            ("NodeTemplateFilter", CINodeFilterDataDefinition.class),;
 
        private String name;
        private Class classOfJson;
index 115f084..7c53688 100644 (file)
@@ -66,6 +66,7 @@ public abstract class Component {
     private String derivedFromGenericVersion;
     private String toscaType;
     protected List<AdditionalInformationDefinition> additionalInformation;
+    protected List<PropertyDefinition> properties;
     private Map<String, InterfaceDefinition> interfaces;
 
     public Map<String, InterfaceDefinition> getInterfaces() {
@@ -533,6 +534,14 @@ public abstract class Component {
         this.policies = policies;
     }
 
+    public List<PropertyDefinition> getProperties() {
+        return properties;
+    }
+
+    public void setProperties(List<PropertyDefinition> properties) {
+        this.properties = properties;
+    }
+
     @Override
     public int hashCode() {
         final int prime = 31;
@@ -555,6 +564,7 @@ public abstract class Component {
         result = prime * result + ((derivedFromGenericType == null) ? 0 : derivedFromGenericType.hashCode());
         result = prime * result + ((derivedFromGenericVersion == null) ? 0 : derivedFromGenericVersion.hashCode());
         result = prime * result + ((interfaces == null) ? 0 : interfaces.hashCode());
+        result = prime * result + ((properties == null) ? 0 : properties.hashCode());
         return result;
     }
 
@@ -691,6 +701,9 @@ public abstract class Component {
         else if (!interfaces.equals(other.interfaces)) {
             return false;
         }
+        else if (!properties.equals(other.properties)) {
+            return false;
+        }
         return true;
     }
 
index 4a62286..ef9b409 100644 (file)
@@ -23,6 +23,7 @@ package org.openecomp.sdc.be.model;
 import org.openecomp.sdc.be.datatypes.elements.ComponentInstanceDataDefinition;
 import org.openecomp.sdc.be.datatypes.elements.PropertiesOwner;
 import org.openecomp.sdc.common.api.ArtifactGroupTypeEnum;
+import org.openecomp.sdc.be.datatypes.elements.CINodeFilterDataDefinition;
 
 import java.util.Collections;
 import java.util.List;
@@ -35,6 +36,7 @@ public class ComponentInstance extends ComponentInstanceDataDefinition implement
     private Map<String, ArtifactDefinition> deploymentArtifacts;
     private Map<String, ArtifactDefinition> artifacts;
     private List<GroupInstance> groupInstances;
+    private CINodeFilterDataDefinition nodeFilter;
 
     public ComponentInstance() {
         super();
@@ -106,4 +108,13 @@ public class ComponentInstance extends ComponentInstanceDataDefinition implement
         }
         return safeGetInformationalArtifacts().get(artifactLabel) != null;
     }
+
+    public CINodeFilterDataDefinition getNodeFilter() {
+        return nodeFilter;
+    }
+
+    public void setNodeFilter(CINodeFilterDataDefinition nodeFilter) {
+        this.nodeFilter = nodeFilter;
+    }
+
 }
diff --git a/catalog-model/src/main/java/org/openecomp/sdc/be/model/UploadNodeFilterCapabilitiesInfo.java b/catalog-model/src/main/java/org/openecomp/sdc/be/model/UploadNodeFilterCapabilitiesInfo.java
new file mode 100644 (file)
index 0000000..2339534
--- /dev/null
@@ -0,0 +1,40 @@
+/*
+ * Copyright © 2016-2018 European Support Limited
+ *
+ * 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.
+ */
+package org.openecomp.sdc.be.model;
+
+import java.util.List;
+
+public class UploadNodeFilterCapabilitiesInfo {
+
+    private String name;
+    private List<UploadNodeFilterPropertyInfo> properties;
+
+    public String getName() {
+        return name;
+    }
+
+    public void setName(String name) {
+        this.name = name;
+    }
+
+    public List<UploadNodeFilterPropertyInfo> getProperties() {
+        return properties;
+    }
+
+    public void setProperties(List<UploadNodeFilterPropertyInfo> properties) {
+        this.properties = properties;
+    }
+}
diff --git a/catalog-model/src/main/java/org/openecomp/sdc/be/model/UploadNodeFilterInfo.java b/catalog-model/src/main/java/org/openecomp/sdc/be/model/UploadNodeFilterInfo.java
new file mode 100644 (file)
index 0000000..2b228d9
--- /dev/null
@@ -0,0 +1,62 @@
+/*
+ * Copyright © 2016-2018 European Support Limited
+ *
+ * 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.
+ */
+
+package org.openecomp.sdc.be.model;
+
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+public class UploadNodeFilterInfo {
+
+    private String name;
+    private Object tosca_id;
+    private List<UploadNodeFilterPropertyInfo> properties = new ArrayList<>();
+    private Map<String, UploadNodeFilterCapabilitiesInfo> capabilities = new HashMap<>();
+
+    public String getName() {
+        return name;
+    }
+
+    public void setName(String name) {
+        this.name = name;
+    }
+
+    public List<UploadNodeFilterPropertyInfo> getProperties() {
+        return properties;
+    }
+
+    public void setProperties(List<UploadNodeFilterPropertyInfo> properties) {
+        this.properties = properties;
+    }
+
+    public Map<String, UploadNodeFilterCapabilitiesInfo> getCapabilities() {
+        return capabilities;
+    }
+
+    public void setCapabilities(Map<String, UploadNodeFilterCapabilitiesInfo> capabilities) {
+        this.capabilities = capabilities;
+    }
+
+    public Object getTosca_id() {
+        return tosca_id;
+    }
+
+    public void setTosca_id(Object tosca_id) {
+        this.tosca_id = tosca_id;
+    }
+}
diff --git a/catalog-model/src/main/java/org/openecomp/sdc/be/model/UploadNodeFilterPropertyInfo.java b/catalog-model/src/main/java/org/openecomp/sdc/be/model/UploadNodeFilterPropertyInfo.java
new file mode 100644 (file)
index 0000000..ea94ca2
--- /dev/null
@@ -0,0 +1,48 @@
+/*
+ * Copyright © 2016-2018 European Support Limited
+ *
+ * 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.
+ */
+package org.openecomp.sdc.be.model;
+
+import java.util.List;
+
+public class UploadNodeFilterPropertyInfo {
+
+    private String name;
+    private List<String> values;
+
+    public UploadNodeFilterPropertyInfo() {
+    }
+
+    public UploadNodeFilterPropertyInfo(String name, List<String> value) {
+        this.name = name;
+        this.values = value;
+    }
+
+    public String getName() {
+        return name;
+    }
+
+    public void setName(String name) {
+        this.name = name;
+    }
+
+    public List<String> getValues() {
+        return values;
+    }
+
+    public void setValue(List<String> values) {
+        this.values = values;
+    }
+}
diff --git a/catalog-model/src/main/java/org/openecomp/sdc/be/model/jsontitan/operations/NodeFilterOperation.java b/catalog-model/src/main/java/org/openecomp/sdc/be/model/jsontitan/operations/NodeFilterOperation.java
new file mode 100644 (file)
index 0000000..989708c
--- /dev/null
@@ -0,0 +1,179 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * SDC
+ * ================================================================================
+ * Copyright (C) 2017 AT&T Intellectual Property. All rights reserved.
+ * ================================================================================
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ * ============LICENSE_END=========================================================
+ */
+
+package org.openecomp.sdc.be.model.jsontitan.operations;
+
+import com.google.common.collect.ImmutableList;
+import com.google.common.collect.ImmutableSet;
+import com.google.common.collect.Sets;
+import fj.data.Either;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.List;
+import java.util.Set;
+import org.openecomp.sdc.be.dao.jsongraph.GraphVertex;
+import org.openecomp.sdc.be.dao.jsongraph.types.EdgeLabelEnum;
+import org.openecomp.sdc.be.dao.jsongraph.types.JsonParseFlagEnum;
+import org.openecomp.sdc.be.dao.jsongraph.types.VertexTypeEnum;
+import org.openecomp.sdc.be.dao.titan.TitanOperationStatus;
+import org.openecomp.sdc.be.datatypes.elements.CINodeFilterDataDefinition;
+import org.openecomp.sdc.be.datatypes.elements.ListDataDefinition;
+import org.openecomp.sdc.be.datatypes.elements.RequirementNodeFilterPropertyDataDefinition;
+import org.openecomp.sdc.be.datatypes.enums.JsonPresentationFields;
+import org.openecomp.sdc.be.model.Service;
+import org.openecomp.sdc.be.model.operations.api.StorageOperationStatus;
+import org.openecomp.sdc.be.model.operations.impl.DaoStatusConverter;
+import org.openecomp.sdc.common.jsongraph.util.CommonUtility;
+import org.openecomp.sdc.common.log.elements.LoggerFactory;
+import org.openecomp.sdc.common.log.wrappers.Logger;
+
+@org.springframework.stereotype.Component("service-filter-operations")
+public class NodeFilterOperation extends BaseOperation {
+
+    private static Logger logger = LoggerFactory.getLogger(NodeFilterOperation.class,
+            org.slf4j.LoggerFactory.getLogger(NodeFilterOperation.class));
+
+    public Either<Set<String>, StorageOperationStatus> deleteNodeFilters(Service service,
+            Set<String> componentInstanceIds) {
+        Either<GraphVertex, TitanOperationStatus> getComponentVertex;
+        Either<GraphVertex, TitanOperationStatus> getNodeFilterVertex;
+        StorageOperationStatus status;
+
+        getComponentVertex = titanDao.getVertexById(service.getUniqueId(), JsonParseFlagEnum.NoParse);
+        if (getComponentVertex.isRight()) {
+            return Either.right(
+                    DaoStatusConverter.convertTitanStatusToStorageStatus(getComponentVertex.right().value()));
+        }
+
+        getNodeFilterVertex =
+                titanDao.getChildVertex(getComponentVertex.left().value(), EdgeLabelEnum.NODE_FILTER_TEMPLATE,
+                        JsonParseFlagEnum.NoParse);
+        if (getNodeFilterVertex.isLeft()) {
+            status = deleteToscaDataElements(service.getUniqueId(), EdgeLabelEnum.NODE_FILTER_TEMPLATE,
+                    new ArrayList<>(componentInstanceIds));
+            if (status != StorageOperationStatus.OK) {
+                return Either.right(status);
+            }
+        }
+
+        return Either.left(componentInstanceIds);
+    }
+
+
+    public Either<String, StorageOperationStatus> deleteNodeFilter(Service service, String componentInstanceId) {
+        final Either<Set<String>, StorageOperationStatus> listStorageOperationStatusEither =
+                deleteNodeFilters(service, ImmutableSet.of(componentInstanceId));
+        if (listStorageOperationStatusEither.isRight()) {
+            return Either.right(listStorageOperationStatusEither.right().value());
+        }
+        return Either.left(componentInstanceId);
+    }
+
+
+    public Either<CINodeFilterDataDefinition, StorageOperationStatus> createNodeFilter(String serviceId,
+            String componentInstanceId) {
+        CINodeFilterDataDefinition nodeFilterDataDefinition = new CINodeFilterDataDefinition();
+        return addOrUpdateNodeFilter(false, serviceId, componentInstanceId, nodeFilterDataDefinition);
+    }
+
+    public Either<CINodeFilterDataDefinition, StorageOperationStatus> deleteConstraint(String serviceId,
+            String componentInstanceId, CINodeFilterDataDefinition nodeFilterDataDefinition, int propertyIndex) {
+        ListDataDefinition<RequirementNodeFilterPropertyDataDefinition> properties =
+                nodeFilterDataDefinition.getProperties();
+        properties.getListToscaDataDefinition().remove(propertyIndex);
+        nodeFilterDataDefinition.setProperties(properties);
+        return addOrUpdateNodeFilter(true, serviceId, componentInstanceId, nodeFilterDataDefinition);
+    }
+
+    public Either<CINodeFilterDataDefinition, StorageOperationStatus> addNewProperty(String serviceId,
+            String componentInstanceId, CINodeFilterDataDefinition nodeFilterDataDefinition,
+            RequirementNodeFilterPropertyDataDefinition requirementNodeFilterPropertyDataDefinition) {
+        ListDataDefinition<RequirementNodeFilterPropertyDataDefinition> properties =
+                nodeFilterDataDefinition.getProperties();
+        if (properties == null) {
+            properties = new ListDataDefinition<>();
+            nodeFilterDataDefinition.setProperties(properties);
+        }
+        properties.getListToscaDataDefinition().add(requirementNodeFilterPropertyDataDefinition);
+        nodeFilterDataDefinition.setProperties(properties);
+        return addOrUpdateNodeFilter(true, serviceId, componentInstanceId, nodeFilterDataDefinition);
+    }
+
+    public Either<CINodeFilterDataDefinition, StorageOperationStatus> updateProperties(String serviceId,
+            String componentInstanceId, CINodeFilterDataDefinition nodeFilterDataDefinition,
+            List<RequirementNodeFilterPropertyDataDefinition> requirementNodeFilterPropertyDataDefinition) {
+        ListDataDefinition<RequirementNodeFilterPropertyDataDefinition> properties =
+                nodeFilterDataDefinition.getProperties();
+        properties.getListToscaDataDefinition().clear();
+        properties.getListToscaDataDefinition().addAll(requirementNodeFilterPropertyDataDefinition);
+        nodeFilterDataDefinition.setProperties(properties);
+        return addOrUpdateNodeFilter(true, serviceId, componentInstanceId, nodeFilterDataDefinition);
+    }
+
+    public Either<CINodeFilterDataDefinition, StorageOperationStatus> updateNodeFilter(String serviceId,
+            String componentInstanceId, CINodeFilterDataDefinition ciNodeFilterDataDefinition) {
+        return addOrUpdateNodeFilter(true, serviceId, componentInstanceId, ciNodeFilterDataDefinition);
+    }
+
+    private Either<CINodeFilterDataDefinition, StorageOperationStatus> addOrUpdateNodeFilter(boolean isUpdateAction,
+            String serviceId, String componentInstanceId, CINodeFilterDataDefinition ciNodeFilterDataDefinition) {
+
+        StorageOperationStatus statusRes;
+        Either<GraphVertex, TitanOperationStatus> getToscaElementRes;
+
+        getToscaElementRes = titanDao.getVertexById(serviceId, JsonParseFlagEnum.NoParse);
+        if (getToscaElementRes.isRight()) {
+            TitanOperationStatus status = getToscaElementRes.right().value();
+            CommonUtility.addRecordToLog(logger, CommonUtility.LogLevelEnum.DEBUG,
+                    "Failed to get tosca element {} upon adding the properties. Status is {}. ", serviceId, status);
+            statusRes = DaoStatusConverter.convertTitanStatusToStorageStatus(status);
+            return Either.right(statusRes);
+        }
+        GraphVertex serviceVertex = getToscaElementRes.left().value();
+        ciNodeFilterDataDefinition.setID(componentInstanceId);
+        statusRes = performUpdateToscaAction(isUpdateAction, serviceVertex, ImmutableList.of(ciNodeFilterDataDefinition));
+        if (!statusRes.equals(StorageOperationStatus.OK)) {
+            titanDao.rollback();
+            logger.error(
+                    " Failed to perform tosca update for node filter in service {} , component instance {}. status is {}",
+                    serviceId, componentInstanceId, statusRes);
+            return Either.right(statusRes);
+        }
+        titanDao.commit();
+        return Either.left(ciNodeFilterDataDefinition);
+
+    }
+
+
+    private StorageOperationStatus performUpdateToscaAction(boolean isUpdate, GraphVertex graphVertex,
+            List<CINodeFilterDataDefinition> toscaDataList) {
+        if (isUpdate) {
+            return updateToscaDataOfToscaElement(graphVertex, EdgeLabelEnum.NODE_FILTER_TEMPLATE,
+                    VertexTypeEnum.NODE_FILTER_TEMPLATE, toscaDataList, JsonPresentationFields.UNIQUE_ID);
+        } else {
+            return addToscaDataToToscaElement(graphVertex, EdgeLabelEnum.NODE_FILTER_TEMPLATE,
+                    VertexTypeEnum.NODE_FILTER_TEMPLATE, toscaDataList, JsonPresentationFields.UNIQUE_ID);
+        }
+    }
+
+}
+
+
+
diff --git a/catalog-model/src/main/java/org/openecomp/sdc/be/ui/model/UIConstraint.java b/catalog-model/src/main/java/org/openecomp/sdc/be/ui/model/UIConstraint.java
new file mode 100644 (file)
index 0000000..63353c1
--- /dev/null
@@ -0,0 +1,117 @@
+/*
+ * Copyright © 2016-2018 European Support Limited
+ *
+ * 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.
+ */
+
+package org.openecomp.sdc.be.ui.model;
+
+import com.google.common.base.MoreObjects;
+import com.google.common.base.Objects;
+import java.io.Serializable;
+
+public class UIConstraint implements Serializable {
+
+    private String servicePropertyName;
+    private String constraintOperator;
+    private String sourceType;
+    private String sourceName;
+    private Object value;
+
+    public UIConstraint() {
+    }
+
+    public UIConstraint(String servicePropertyName, String constraintOperator, String sourceType, Object value) {
+        this.servicePropertyName = servicePropertyName;
+        this.constraintOperator = constraintOperator;
+        this.sourceType = sourceType;
+        this.value = value;
+    }
+
+    public UIConstraint(String servicePropertyName, String constraintOperator, String sourceType, String sourceName,
+            Object value) {
+        this.servicePropertyName = servicePropertyName;
+        this.constraintOperator = constraintOperator;
+        this.sourceType = sourceType;
+        this.sourceName = sourceName;
+        this.value = value;
+    }
+
+    public String getServicePropertyName() {
+        return servicePropertyName;
+    }
+
+    public void setServicePropertyName(String servicePropertyName) {
+        this.servicePropertyName = servicePropertyName;
+    }
+
+    public String getConstraintOperator() {
+        return constraintOperator;
+    }
+
+    public void setConstraintOperator(String constraintOperator) {
+        this.constraintOperator = constraintOperator;
+    }
+
+    public String getSourceType() {
+        return sourceType;
+    }
+
+    public void setSourceType(String sourceType) {
+        this.sourceType = sourceType;
+    }
+
+    public Object getValue() {
+        return value;
+    }
+
+    public void setValue(Object value) {
+        this.value = value;
+    }
+
+    public String getSourceName() {
+        return sourceName;
+    }
+
+    public void setSourceName(String sourceName) {
+        this.sourceName = sourceName;
+    }
+
+    @Override
+    public boolean equals(Object o) {
+        if (this == o) {
+            return true;
+        }
+        if (!(o instanceof UIConstraint)) {
+            return false;
+        }
+        UIConstraint that = (UIConstraint) o;
+        return Objects.equal(getServicePropertyName(), that.getServicePropertyName()) && Objects.equal(
+                getConstraintOperator(), that.getConstraintOperator()) && Objects.equal(getSourceType(),
+                that.getSourceType()) && Objects.equal(getSourceName(), that.getSourceName()) && Objects.equal(
+                getValue(), that.getValue());
+    }
+
+    @Override
+    public int hashCode() {
+        return Objects.hashCode(getServicePropertyName(), getConstraintOperator(), getSourceType(), getSourceName(),
+                getValue());
+    }
+
+    @Override
+    public String toString() {
+        return MoreObjects.toStringHelper(this).add("servicePropertyName", servicePropertyName)
+                          .add("constraintOperator", constraintOperator).add("sourceType", sourceType)
+                          .add("sourceName", sourceName).add("value", value).toString();
+    }
+}
diff --git a/catalog-model/src/main/java/org/openecomp/sdc/be/ui/model/UINodeFilter.java b/catalog-model/src/main/java/org/openecomp/sdc/be/ui/model/UINodeFilter.java
new file mode 100644 (file)
index 0000000..16ce3a8
--- /dev/null
@@ -0,0 +1,31 @@
+/*
+ * Copyright © 2016-2018 European Support Limited
+ *
+ * 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.
+ */
+package org.openecomp.sdc.be.ui.model;
+
+import java.util.List;
+
+public class UINodeFilter {
+
+    private List<UIConstraint> properties;
+
+    public List<UIConstraint> getProperties() {
+        return properties;
+    }
+
+    public void setProperties(List<UIConstraint> properties) {
+        this.properties = properties;
+    }
+}
diff --git a/common-be/src/main/java/org/openecomp/sdc/be/datatypes/elements/CINodeFilterDataDefinition.java b/common-be/src/main/java/org/openecomp/sdc/be/datatypes/elements/CINodeFilterDataDefinition.java
new file mode 100644 (file)
index 0000000..ffad1a4
--- /dev/null
@@ -0,0 +1,81 @@
+/*
+ * Copyright © 2016-2018 European Support Limited
+ *
+ * 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.
+ */
+package org.openecomp.sdc.be.datatypes.elements;
+
+import com.fasterxml.jackson.annotation.JsonCreator;
+import java.io.Serializable;
+import org.openecomp.sdc.be.datatypes.enums.JsonPresentationFields;
+import org.openecomp.sdc.be.datatypes.tosca.ToscaDataDefinition;
+
+public class CINodeFilterDataDefinition extends ToscaDataDefinition implements Serializable {
+
+    @JsonCreator
+    public CINodeFilterDataDefinition() {
+    }
+
+    public CINodeFilterDataDefinition(CINodeFilterDataDefinition inData){
+        super();
+        this.setID(inData.getID());
+        this.setName(inData.getName());
+        this.setTosca_id(inData.getTosca_id());
+        this.setProperties(inData.getProperties());
+        this.setCapabilities(inData.getCapabilities());
+    }
+
+    public void setTosca_id(Object tosca_id) {
+        setToscaPresentationValue(JsonPresentationFields.TOSCA_ID, tosca_id);
+    }
+
+    public Object getTosca_id() {
+        return getToscaPresentationValue(JsonPresentationFields.TOSCA_ID);
+    }
+
+    public ListDataDefinition<RequirementNodeFilterPropertyDataDefinition> getProperties() {
+        return (ListDataDefinition<RequirementNodeFilterPropertyDataDefinition>) getToscaPresentationValue(
+                JsonPresentationFields.PROPERTIES);
+    }
+
+    public void setProperties(ListDataDefinition<RequirementNodeFilterPropertyDataDefinition> properties) {
+        setToscaPresentationValue(JsonPresentationFields.PROPERTIES, properties);
+    }
+
+    public ListDataDefinition<RequirementNodeFilterCapabilityDataDefinition> getCapabilities() {
+        return (ListDataDefinition<RequirementNodeFilterCapabilityDataDefinition>) getToscaPresentationValue(
+                JsonPresentationFields.NODE_FILTER_CAPABILITIES);
+    }
+
+    public void setCapabilities(ListDataDefinition<RequirementNodeFilterCapabilityDataDefinition> capabilities) {
+        setToscaPresentationValue(JsonPresentationFields.NODE_FILTER_CAPABILITIES, capabilities);
+    }
+
+    public String getName() {
+        return (String) getToscaPresentationValue(JsonPresentationFields.NAME);
+    }
+
+    public void setName(String name) {
+        setToscaPresentationValue(JsonPresentationFields.NAME, name);
+    }
+
+    public String getID() {
+        return (String) getToscaPresentationValue(JsonPresentationFields.UNIQUE_ID);
+    }
+
+    public void setID(String name) {
+        setToscaPresentationValue(JsonPresentationFields.UNIQUE_ID, name);
+    }
+
+
+}
diff --git a/common-be/src/main/java/org/openecomp/sdc/be/datatypes/elements/RequirementNodeFilterCapabilityDataDefinition.java b/common-be/src/main/java/org/openecomp/sdc/be/datatypes/elements/RequirementNodeFilterCapabilityDataDefinition.java
new file mode 100644 (file)
index 0000000..3df0f28
--- /dev/null
@@ -0,0 +1,47 @@
+/*
+ * Copyright © 2016-2018 European Support Limited
+ *
+ * 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.
+ */
+
+package org.openecomp.sdc.be.datatypes.elements;
+
+import java.io.Serializable;
+import org.openecomp.sdc.be.datatypes.enums.JsonPresentationFields;
+import org.openecomp.sdc.be.datatypes.tosca.ToscaDataDefinition;
+
+public class RequirementNodeFilterCapabilityDataDefinition extends ToscaDataDefinition implements Serializable {
+
+    /**
+     * Default Constructor
+     */
+    public RequirementNodeFilterCapabilityDataDefinition() {
+    }
+
+    public String getName() {
+        return (String) getToscaPresentationValue(JsonPresentationFields.NAME);
+    }
+
+    public void setName(String name) {
+        setToscaPresentationValue(JsonPresentationFields.NAME, name);
+    }
+
+    public ListDataDefinition<RequirementNodeFilterPropertyDataDefinition> getProperties() {
+        return (ListDataDefinition<RequirementNodeFilterPropertyDataDefinition>) getToscaPresentationValue(
+                JsonPresentationFields.PROPERTIES);
+    }
+
+    public void setProperties(ListDataDefinition<RequirementNodeFilterPropertyDataDefinition> properties) {
+        setToscaPresentationValue(JsonPresentationFields.PROPERTIES, properties);
+    }
+}
diff --git a/common-be/src/main/java/org/openecomp/sdc/be/datatypes/elements/RequirementNodeFilterPropertyDataDefinition.java b/common-be/src/main/java/org/openecomp/sdc/be/datatypes/elements/RequirementNodeFilterPropertyDataDefinition.java
new file mode 100644 (file)
index 0000000..1ee33ee
--- /dev/null
@@ -0,0 +1,41 @@
+/*
+ * Copyright © 2016-2018 European Support Limited
+ *
+ * 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.
+ */
+package org.openecomp.sdc.be.datatypes.elements;
+
+import java.io.Serializable;
+import java.util.List;
+import org.openecomp.sdc.be.datatypes.enums.JsonPresentationFields;
+import org.openecomp.sdc.be.datatypes.tosca.ToscaDataDefinition;
+
+public class RequirementNodeFilterPropertyDataDefinition extends ToscaDataDefinition implements Serializable {
+
+
+    public List<String> getConstraints() {
+        return (List<String>) getToscaPresentationValue(JsonPresentationFields.PROPERTY_FILTER_CONSTRAINT);
+    }
+
+    public void setConstraints(List<String> constraints) {
+        setToscaPresentationValue(JsonPresentationFields.PROPERTY_FILTER_CONSTRAINT, constraints);
+    }
+
+    public String getName() {
+        return (String) getToscaPresentationValue(JsonPresentationFields.PROPERTY_FILTER_NAME);
+    }
+
+    public void setName(String name) {
+        setToscaPresentationValue(JsonPresentationFields.PROPERTY_FILTER_NAME, name);
+    }
+}
index db0735a..abc426c 100644 (file)
@@ -44,6 +44,7 @@ public enum ComponentFieldsEnum {
     FORWARDING_PATHS("forwardingPaths"),
     POLICIES("policies"),
     NON_EXCLUDED_POLICIES("nonExcludedPolicies"),
+    NODE_FILTER("nodeFilter")
     ;
 
 
index 40d6a70..6829c72 100644 (file)
@@ -136,6 +136,15 @@ public enum JsonPresentationFields {
     REQUIREMENT_ID("requirementId", null),
     PARENT_NAME("parentName", null),
     PREVIOUS_NAME("previousName", null),
+    NODE_FILTER_CAPABILITIES("capabilities",null),
+    PROPERTY_FILTER_NAME("propertyName",null),
+    PROPERTY_FILTER_CONSTRAINT("propertyFilterConstraint",null),
+    EQUAL_CONSTRAINT("equal",null),
+    CONSTRAINT_VALUE("constraintValue",null),
+    CONSTRAINT_FUNCTION("constraintFunction",null),
+    NODE_FILTER("nodeFilter",null),
+    TOSCA_ID("tosca_id",null),
+
     //Relation
     CAPABILTY_OWNER_ID("capabilityOwnerId", null),
     REQUIREMENT_OWNER_ID("requirementOwnerId", null),