diff options
Diffstat (limited to 'catalog-be/src')
12 files changed, 1805 insertions, 0 deletions
diff --git a/catalog-be/src/main/java/org/openecomp/sdc/be/components/impl/ServiceBusinessLogic.java b/catalog-be/src/main/java/org/openecomp/sdc/be/components/impl/ServiceBusinessLogic.java index 8d4f896d47..9bf442990b 100644 --- a/catalog-be/src/main/java/org/openecomp/sdc/be/components/impl/ServiceBusinessLogic.java +++ b/catalog-be/src/main/java/org/openecomp/sdc/be/components/impl/ServiceBusinessLogic.java @@ -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 index 0000000000..73ec3352b3 --- /dev/null +++ b/catalog-be/src/main/java/org/openecomp/sdc/be/components/impl/utils/CINodeFilterUtils.java @@ -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 index 0000000000..32f49b3849 --- /dev/null +++ b/catalog-be/src/main/java/org/openecomp/sdc/be/components/impl/utils/NodeFilterConstraintAction.java @@ -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 index 0000000000..8d2808851b --- /dev/null +++ b/catalog-be/src/main/java/org/openecomp/sdc/be/components/validation/NodeFilterValidator.java @@ -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 index 0000000000..e05ef92431 --- /dev/null +++ b/catalog-be/src/main/java/org/openecomp/sdc/be/datamodel/utils/ConstraintConvertor.java @@ -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 index 0000000000..3daca3f28c --- /dev/null +++ b/catalog-be/src/main/java/org/openecomp/sdc/be/servlets/ServiceFilterServlet.java @@ -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 index 0000000000..58a9a759bf --- /dev/null +++ b/catalog-be/src/main/java/org/openecomp/sdc/be/tosca/model/CapabilityFilter.java @@ -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 index 0000000000..79e9f57209 --- /dev/null +++ b/catalog-be/src/main/java/org/openecomp/sdc/be/tosca/model/NodeFilter.java @@ -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 index 0000000000..af0837fdcf --- /dev/null +++ b/catalog-be/src/main/java/org/openecomp/sdc/be/tosca/utils/NodeFilterConverter.java @@ -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; + } +} diff --git a/catalog-be/src/main/resources/config/error-configuration.yaml b/catalog-be/src/main/resources/config/error-configuration.yaml index 315027b43e..69f67e63ed 100644 --- a/catalog-be/src/main/resources/config/error-configuration.yaml +++ b/catalog-be/src/main/resources/config/error-configuration.yaml @@ -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 index 0000000000..fe9827f362 --- /dev/null +++ b/catalog-be/src/test/java/org/openecomp/sdc/be/components/validation/NodeFilterValidationTest.java @@ -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 index 0000000000..942a279ec7 --- /dev/null +++ b/catalog-be/src/test/java/org/openecomp/sdc/be/tosca/model/ConstraintConvertorTest.java @@ -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); + } +} |