diff options
author | shrek2000 <orenkle@amdocs.com> | 2019-01-29 13:04:42 +0200 |
---|---|---|
committer | Avi Gaffa <avi.gaffa@amdocs.com> | 2019-01-30 12:18:32 +0000 |
commit | ade7fd243fe41b5056ba63d3584ea616ee8bf808 (patch) | |
tree | 4be93c8ddfd4577b29fe8553f92d2bd17dbe89b4 /catalog-be/src/main/java | |
parent | 614136b09c5d11bec99fe3c1e23e8c9e022eaa58 (diff) |
Add dependent child service to service
Add dependent child service to service
Issue-ID: SDC-1987
Change-Id: Ic542fe1bc13f2b77df9944f05421a42b4b21c437
Signed-off-by: shrek2000 <orenkle@amdocs.com>
Diffstat (limited to 'catalog-be/src/main/java')
9 files changed, 1280 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; + } +} |