From 5b9d9a134778d4dc7bf45474ba13be6ba0c46282 Mon Sep 17 00:00:00 2001 From: priyanshu Date: Mon, 14 Jan 2019 15:46:55 +0530 Subject: Interface operation feature enhancements 1. API restructuring to enhance model and provide more capabilities. 2. Allowed multiple interface creation under same resource/service. 3. Enhanced validations to align with updated model. 4. API restructuring to align UI model with Tosca model. 5. Enhanced Junit and code coverage. 6. Added BDD and CI-API tests. Change-Id: I2d8ac8a6154fd9be8254836ba0da1540210031c0 Issue-ID: SDC-1999 Signed-off-by: priyanshu --- .../be/components/impl/ArtifactsBusinessLogic.java | 56 +-- .../sdc/be/components/impl/BaseBusinessLogic.java | 17 +- .../impl/InterfaceOperationBusinessLogic.java | 479 ++++++++++++--------- .../be/components/impl/ResourceBusinessLogic.java | 8 - .../be/components/impl/ServiceBusinessLogic.java | 6 +- .../components/utils/InterfaceOperationUtils.java | 64 +++ .../validation/InterfaceOperationValidation.java | 407 +++++++++-------- .../datamodel/utils/InterfaceUIDataConverter.java | 106 ----- .../servlet/ArtifactExternalServlet.java | 13 +- .../sdc/be/servlets/InterfaceOperationServlet.java | 426 ++++++++++-------- .../sdc/be/servlets/RepresentationUtils.java | 18 +- .../openecomp/sdc/be/tosca/ToscaExportHandler.java | 23 +- .../tosca/utils/InterfacesOperationsToscaUtil.java | 42 +- 13 files changed, 916 insertions(+), 749 deletions(-) create mode 100644 catalog-be/src/main/java/org/openecomp/sdc/be/components/utils/InterfaceOperationUtils.java delete mode 100644 catalog-be/src/main/java/org/openecomp/sdc/be/datamodel/utils/InterfaceUIDataConverter.java (limited to 'catalog-be/src/main/java/org') diff --git a/catalog-be/src/main/java/org/openecomp/sdc/be/components/impl/ArtifactsBusinessLogic.java b/catalog-be/src/main/java/org/openecomp/sdc/be/components/impl/ArtifactsBusinessLogic.java index 2b3ee0ed2e..8f1f5864d5 100644 --- a/catalog-be/src/main/java/org/openecomp/sdc/be/components/impl/ArtifactsBusinessLogic.java +++ b/catalog-be/src/main/java/org/openecomp/sdc/be/components/impl/ArtifactsBusinessLogic.java @@ -56,7 +56,7 @@ import org.openecomp.sdc.be.model.*; import org.openecomp.sdc.be.model.heat.HeatParameterType; import org.openecomp.sdc.be.model.jsontitan.operations.InterfaceOperation; import org.openecomp.sdc.be.model.jsontitan.operations.NodeTemplateOperation; -import org.openecomp.sdc.be.model.jsontitan.utils.InterfaceUtils; +import org.openecomp.sdc.be.components.utils.InterfaceOperationUtils; import org.openecomp.sdc.be.model.operations.api.*; import org.openecomp.sdc.be.model.operations.impl.DaoStatusConverter; import org.openecomp.sdc.be.model.operations.impl.UniqueIdBuilder; @@ -179,9 +179,6 @@ public class ArtifactsBusinessLogic extends BaseBusinessLogic { @Autowired private ArtifactsResolver artifactsResolver; - @Autowired - private InterfaceOperation interfaceOperation; - public enum ArtifactOperationEnum { CREATE, UPDATE, DELETE, DOWNLOAD, LINK; @@ -3058,7 +3055,7 @@ public class ArtifactsBusinessLogic extends BaseBusinessLogic { } } else { return updateArtifactsFlowForInterfaceOperations(parent, parentId, artifactId, artifactInfo, user, - decodedPayload, componentType, auditingAction, operationUuid, artifactData, prevArtifactId, + decodedPayload, componentType, auditingAction, interfaceType, operationUuid, artifactData, prevArtifactId, currArtifactId, artifactDefinition); } @@ -3067,7 +3064,7 @@ public class ArtifactsBusinessLogic extends BaseBusinessLogic { private Either, ResponseFormat> updateArtifactsFlowForInterfaceOperations( Component parent, String parentId, String artifactId, ArtifactDefinition artifactInfo, User user, - byte[] decodedPayload, ComponentTypeEnum componentType, AuditingActionEnum auditingAction, + byte[] decodedPayload, ComponentTypeEnum componentType, AuditingActionEnum auditingAction, String interfaceType, String operationUuid, ESArtifactData artifactData, String prevArtifactId, String currArtifactId, ArtifactDefinition artifactDefinition) { StorageOperationStatus error; @@ -3110,24 +3107,15 @@ public class ArtifactsBusinessLogic extends BaseBusinessLogic { } Component storedComponent = componentStorageOperationStatusEither.left().value(); - String interfaceToscaName = InterfaceUtils.createInterfaceToscaResourceName( - storedComponent.getName()); - //fetch the interface from storage - Optional interfaceDefinition = - storedComponent.getInterfaces().values().stream() - .filter(interfaceDef -> interfaceDef.getToscaResourceName() - .equals(interfaceToscaName)).findFirst(); - if (!interfaceDefinition.isPresent()) { + Optional optionalInterface = InterfaceOperationUtils + .getInterfaceDefinitionFromComponentByInterfaceType(storedComponent, interfaceType); + if(!optionalInterface.isPresent()) { log.debug("Failed to get resource interface for resource Id {}", parentId); - ResponseFormat responseFormat = componentsUtils.getResponseFormat( - ActionStatus.INTERFACE_OPERATION_NOT_FOUND, parentId); - handleAuditing(auditingAction, parent, parentId, user, artifactInfo, prevArtifactId, - currArtifactId, responseFormat, componentType, null); - return Either.right(responseFormat); + return Either.right(componentsUtils.getResponseFormat(ActionStatus.INTERFACE_NOT_FOUND_IN_COMPONENT, interfaceType)); } //fetch the operation from storage - InterfaceDefinition gotInterface = interfaceDefinition.get(); + InterfaceDefinition gotInterface = optionalInterface.get(); Map operationsMap = gotInterface.getOperationsMap(); Optional optionalOperation = operationsMap.values() .stream() @@ -3152,8 +3140,8 @@ public class ArtifactsBusinessLogic extends BaseBusinessLogic { implementationArtifact.setEsId(artifactInfo.getEsId()); operation.setImplementation(implementationArtifact); gotInterface.setOperationsMap(operationsMap); - Either interfaceDefinitionStorageOperationStatusEither = - interfaceOperation.updateInterface(storedComponent.getUniqueId(), gotInterface); + Either, StorageOperationStatus> interfaceDefinitionStorageOperationStatusEither = + interfaceOperation.updateInterfaces(storedComponent.getUniqueId(), Collections.singletonList(gotInterface)); if (interfaceDefinitionStorageOperationStatusEither.isRight()){ StorageOperationStatus storageOperationStatus = interfaceDefinitionStorageOperationStatusEither.right().value(); ActionStatus actionStatus = @@ -5027,13 +5015,13 @@ public class ArtifactsBusinessLogic extends BaseBusinessLogic { * @param componentType * @param componentUuid * @param artifactUUID - * @param operation TODO + * @param operation * @return */ public Either updateArtifactOnInterfaceOperationByResourceUUID( String data, HttpServletRequest request, ComponentTypeEnum componentType, - String componentUuid, String artifactUUID, String operationUUID, - ResourceCommonInfo resourceCommonInfo,ArtifactOperationInfo operation) { + String componentUuid, String interfaceUUID, String operationUUID, String artifactUUID, + ResourceCommonInfo resourceCommonInfo,ArtifactOperationInfo operation) { Wrapper errorWrapper = new Wrapper<>(); Either updateArtifactResult; Either, ResponseFormat> actionResult = null; @@ -5067,7 +5055,7 @@ public class ArtifactsBusinessLogic extends BaseBusinessLogic { resourceCommonInfo.setResourceName(componentName); } if (errorWrapper.isEmpty()) { - Either interfaceName = fetchInterfaceName(componentId); + Either interfaceName = fetchInterfaceName(componentId, interfaceUUID); if (interfaceName.isRight()) { errorWrapper.setInnerElement(interfaceName.right().value()); } @@ -5094,19 +5082,21 @@ public class ArtifactsBusinessLogic extends BaseBusinessLogic { return updateArtifactResult; } - private Either fetchInterfaceName(String componentId) { - Either componentStorageOperationStatusEither = - toscaOperationFacade.getToscaElement(componentId); + private Either fetchInterfaceName(String componentId, String interfaceUUID) { + Either componentStorageOperationStatusEither = toscaOperationFacade.getToscaElement(componentId); if (componentStorageOperationStatusEither.isRight()) { StorageOperationStatus errorStatus = componentStorageOperationStatusEither.right().value(); log.debug("Failed to fetch component information by component id, error {}", errorStatus); - return Either.right(componentsUtils - .getResponseFormat(componentsUtils.convertFromStorageResponse(errorStatus))); + return Either.right(componentsUtils.getResponseFormat(componentsUtils.convertFromStorageResponse(errorStatus))); } Component storedComponent = componentStorageOperationStatusEither.left().value(); - return Either.left(InterfaceUtils.createInterfaceToscaResourceName( - storedComponent.getName())); + Optional optionalInterface = InterfaceOperationUtils + .getInterfaceDefinitionFromComponentByInterfaceId(storedComponent, interfaceUUID); + if(!optionalInterface.isPresent()) { + return Either.right(componentsUtils.getResponseFormat(ActionStatus.INTERFACE_NOT_FOUND_IN_COMPONENT, interfaceUUID)); + } + return Either.left(optionalInterface.get().getType()); } diff --git a/catalog-be/src/main/java/org/openecomp/sdc/be/components/impl/BaseBusinessLogic.java b/catalog-be/src/main/java/org/openecomp/sdc/be/components/impl/BaseBusinessLogic.java index 02e64334f9..8ee1864862 100644 --- a/catalog-be/src/main/java/org/openecomp/sdc/be/components/impl/BaseBusinessLogic.java +++ b/catalog-be/src/main/java/org/openecomp/sdc/be/components/impl/BaseBusinessLogic.java @@ -128,10 +128,7 @@ public abstract class BaseBusinessLogic { protected InterfaceOperation interfaceOperation; @Autowired - protected InterfaceOperationBusinessLogic interfaceOperationBusinessLogic; - - @Autowired - protected InterfaceLifecycleOperation interfaceLifecycleOperation; + protected InterfaceLifecycleOperation interfaceLifecycleTypeOperation; @javax.annotation.Resource private UserValidations userValidations; @@ -167,18 +164,6 @@ public abstract class BaseBusinessLogic { this.propertyOperation = propertyOperation; } - public void setInterfaceOperation(InterfaceOperation interfaceOperation) { - this.interfaceOperation = interfaceOperation; - } - public void setInterfaceOperationBusinessLogic(InterfaceOperationBusinessLogic interfaceOperationBusinessLogic) { - this.interfaceOperationBusinessLogic = interfaceOperationBusinessLogic; - } - - - public void setInterfaceLifecycleOperation(InterfaceLifecycleOperation interfaceLifecycleOperation) { - this.interfaceLifecycleOperation = interfaceLifecycleOperation; - } - User validateUserNotEmpty(User user, String ecompErrorContext) { return userValidations.validateUserNotEmpty(user, ecompErrorContext); } diff --git a/catalog-be/src/main/java/org/openecomp/sdc/be/components/impl/InterfaceOperationBusinessLogic.java b/catalog-be/src/main/java/org/openecomp/sdc/be/components/impl/InterfaceOperationBusinessLogic.java index a0efddbdda..2fb7b0f09e 100644 --- a/catalog-be/src/main/java/org/openecomp/sdc/be/components/impl/InterfaceOperationBusinessLogic.java +++ b/catalog-be/src/main/java/org/openecomp/sdc/be/components/impl/InterfaceOperationBusinessLogic.java @@ -18,15 +18,28 @@ package org.openecomp.sdc.be.components.impl; import fj.data.Either; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.Collection; +import java.util.Collections; +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import java.util.Objects; +import java.util.Optional; +import java.util.UUID; +import java.util.stream.Collectors; +import org.openecomp.sdc.be.components.utils.InterfaceOperationUtils; import org.openecomp.sdc.be.components.validation.InterfaceOperationValidation; import org.openecomp.sdc.be.dao.api.ActionStatus; -import org.openecomp.sdc.be.datatypes.enums.ComponentTypeEnum; +import org.openecomp.sdc.be.dao.cassandra.ArtifactCassandraDao; +import org.openecomp.sdc.be.dao.cassandra.CassandraOperationStatus; +import org.openecomp.sdc.be.datatypes.elements.OperationDataDefinition; import org.openecomp.sdc.be.datatypes.enums.NodeTypeEnum; import org.openecomp.sdc.be.model.ArtifactDefinition; import org.openecomp.sdc.be.model.InterfaceDefinition; import org.openecomp.sdc.be.model.Operation; import org.openecomp.sdc.be.model.User; -import org.openecomp.sdc.be.model.jsontitan.utils.InterfaceUtils; import org.openecomp.sdc.be.model.operations.api.StorageOperationStatus; import org.openecomp.sdc.common.api.ArtifactGroupTypeEnum; import org.openecomp.sdc.common.api.ArtifactTypeEnum; @@ -36,305 +49,375 @@ import org.slf4j.LoggerFactory; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Component; -import java.util.Collection; -import java.util.Collections; -import java.util.Map; -import java.util.Optional; -import java.util.UUID; -import java.util.stream.Collectors; - @Component("interfaceOperationBusinessLogic") public class InterfaceOperationBusinessLogic extends BaseBusinessLogic { private static final Logger LOGGER = LoggerFactory.getLogger(InterfaceOperationBusinessLogic.class); - private static final String FAILED_TO_LOCK_COMPONENT_RESPONSE_IS = "Failed to lock component {}. Response is {}"; - private static final String EXCEPTION_OCCURRED_DURING_INTERFACE_OPERATION = "Exception occurred during {}. Response is {}"; + private static final String EXCEPTION_OCCURRED_DURING_INTERFACE_OPERATION = + "Exception occurred during {}. Response is {}"; private static final String DELETE_INTERFACE_OPERATION = "deleteInterfaceOperation"; private static final String GET_INTERFACE_OPERATION = "getInterfaceOperation"; private static final String CREATE_INTERFACE_OPERATION = "createInterfaceOperation"; private static final String UPDATE_INTERFACE_OPERATION = "updateInterfaceOperation"; + @Autowired + private ArtifactCassandraDao artifactCassandraDao; + @Autowired private InterfaceOperationValidation interfaceOperationValidation; - public void setInterfaceOperationValidation(InterfaceOperationValidation interfaceOperationValidation) { - this.interfaceOperationValidation = interfaceOperationValidation; - } + public Either, ResponseFormat> deleteInterfaceOperation(String componentId, + String interfaceId, List operationsToDelete, User user, boolean lock) { + validateUserExists(user.getUserId(), DELETE_INTERFACE_OPERATION, true); - public Either deleteInterfaceOperation(String componentId, String interfaceOperationToDelete, User user, boolean lock) { Either componentEither = getComponentDetails(componentId); - if (componentEither.isRight()){ + if (componentEither.isRight()) { return Either.right(componentEither.right().value()); } org.openecomp.sdc.be.model.Component storedComponent = componentEither.left().value(); - validateUserExists(user.getUserId(), DELETE_INTERFACE_OPERATION, true); - Either lockResult = lockComponentResult(lock, storedComponent, DELETE_INTERFACE_OPERATION); + Either lockResult = + lockComponentResult(lock, storedComponent, DELETE_INTERFACE_OPERATION); if (lockResult.isRight()) { return Either.right(lockResult.right().value()); } try { - Optional optionalInterface = InterfaceUtils.getInterfaceDefinitionFromToscaName(storedComponent.getInterfaces().values(), storedComponent.getName()); - Either getInterfaceEither = getInterfaceDefinition(storedComponent, optionalInterface.orElse(null)); - if (getInterfaceEither.isRight()) { - return Either.right(getInterfaceEither.right().value()); + Optional optionalInterface = InterfaceOperationUtils + .getInterfaceDefinitionFromComponentByInterfaceId( + storedComponent, interfaceId); + if (!optionalInterface.isPresent()) { + return Either.right( + componentsUtils.getResponseFormat(ActionStatus.INTERFACE_NOT_FOUND_IN_COMPONENT, interfaceId)); + } + InterfaceDefinition interfaceDefinition = optionalInterface.get(); + + Map operationsCollection = new HashMap<>(); + for (String operationId : operationsToDelete) { + Optional> optionalOperation = + InterfaceOperationUtils.getOperationFromInterfaceDefinition(interfaceDefinition, operationId); + if (!optionalOperation.isPresent()) { + return Either.right(componentsUtils.getResponseFormat(ActionStatus.INTERFACE_OPERATION_NOT_FOUND, + storedComponent.getUniqueId())); + } + + Operation storedOperation = optionalOperation.get().getValue(); + String artifactUuId = storedOperation.getImplementation().getArtifactUUID(); + CassandraOperationStatus cassandraStatus = artifactCassandraDao.deleteArtifact(artifactUuId); + if (cassandraStatus != CassandraOperationStatus.OK) { + ResponseFormat responseFormatByArtifactId = componentsUtils.getResponseFormatByArtifactId( + componentsUtils.convertFromStorageResponse( + componentsUtils.convertToStorageOperationStatus(cassandraStatus)), + storedOperation.getImplementation().getArtifactDisplayName()); + return Either.right(responseFormatByArtifactId); + } + + operationsCollection.put(operationId, interfaceDefinition.getOperationsMap().get(operationId)); + interfaceDefinition.getOperations().remove(operationId); } - InterfaceDefinition interfaceDefinition = getInterfaceEither.left().value(); - Either getOperationEither = getOperationFromInterfaceDef(storedComponent, interfaceDefinition, interfaceOperationToDelete); - if (getOperationEither.isRight()){ - return Either.right(getOperationEither.right().value()); + Either, StorageOperationStatus> deleteOperationEither = + interfaceOperation.updateInterfaces(storedComponent.getUniqueId(), + Collections.singletonList(interfaceDefinition)); + if (deleteOperationEither.isRight()) { + titanDao.rollback(); + return Either.right(componentsUtils.getResponseFormat(componentsUtils.convertFromStorageResponse( + deleteOperationEither.right().value(), storedComponent.getComponentType()))); } - Either deleteEither = interfaceOperation.deleteInterfaceOperation(componentId, interfaceDefinition, interfaceOperationToDelete); - if (deleteEither.isRight()){ - LOGGER.error("Failed to delete interface operation from component {}. Response is {}", storedComponent.getName(), deleteEither.right().value()); - return Either.right(componentsUtils.getResponseFormat(componentsUtils.convertFromStorageResponse(deleteEither.right().value(), storedComponent.getComponentType()))); + if (interfaceDefinition.getOperations().isEmpty()) { + Either deleteInterfaceEither = interfaceOperation.deleteInterface( + storedComponent.getUniqueId(), interfaceDefinition.getUniqueId()); + if (deleteInterfaceEither.isRight()) { + titanDao.rollback(); + return Either.right(componentsUtils.getResponseFormat(componentsUtils.convertFromStorageResponse( + deleteInterfaceEither.right().value(), storedComponent.getComponentType()))); + } } titanDao.commit(); - return Either.left(deleteEither.left().value()); - } - catch (Exception e){ + interfaceDefinition.getOperations().putAll(operationsCollection); + interfaceDefinition.getOperations().keySet().removeIf(key -> !(operationsToDelete.contains(key))); + return Either.left(Collections.singletonList(interfaceDefinition)); + } catch (Exception e) { LOGGER.error(EXCEPTION_OCCURRED_DURING_INTERFACE_OPERATION, "delete", e); titanDao.rollback(); return Either.right(componentsUtils.getResponseFormat(ActionStatus.INTERFACE_OPERATION_NOT_DELETED)); - } - finally { + } finally { if (lockResult.isLeft() && lockResult.left().value()) { - graphLockOperation.unlockComponent(storedComponent.getUniqueId(), NodeTypeEnum.getByNameIgnoreCase(storedComponent.getComponentType().getValue())); + graphLockOperation.unlockComponent(storedComponent.getUniqueId(), + NodeTypeEnum.getByNameIgnoreCase(storedComponent.getComponentType().getValue())); } } } - public Either getInterfaceOperation(String componentId, String interfaceOperationToGet, User user, boolean lock) { + private Either getComponentDetails(String componentId) { + Either componentStorageOperationStatusEither = + toscaOperationFacade.getToscaElement(componentId); + if (componentStorageOperationStatusEither.isRight()) { + return Either.right(componentsUtils.getResponseFormat( + componentsUtils.convertFromStorageResponse(componentStorageOperationStatusEither.right().value()))); + } + return Either.left(componentStorageOperationStatusEither.left().value()); + } + + private Either lockComponentResult(boolean lock, + org.openecomp.sdc.be.model.Component component, String action) { + if (lock) { + Either lockResult = lockComponent(component.getUniqueId(), component, action); + if (lockResult.isRight()) { + titanDao.rollback(); + return Either.right(lockResult.right().value()); + } + } + return Either.left(true); + } + + public Either, ResponseFormat> getInterfaceOperation(String componentId, + String interfaceId, List operationsToGet, User user, boolean lock) { + validateUserExists(user.getUserId(), GET_INTERFACE_OPERATION, true); + Either componentEither = getComponentDetails(componentId); - if (componentEither.isRight()){ + if (componentEither.isRight()) { return Either.right(componentEither.right().value()); } org.openecomp.sdc.be.model.Component storedComponent = componentEither.left().value(); - validateUserExists(user.getUserId(), GET_INTERFACE_OPERATION, true); - Either lockResult = lockComponentResult(lock, storedComponent, GET_INTERFACE_OPERATION); + Either lockResult = + lockComponentResult(lock, storedComponent, GET_INTERFACE_OPERATION); if (lockResult.isRight()) { return Either.right(lockResult.right().value()); } try { - Optional optionalInterface = InterfaceUtils.getInterfaceDefinitionFromToscaName(storedComponent.getInterfaces().values(), storedComponent.getName()); - Either getInterfaceEither = getInterfaceDefinition(storedComponent, optionalInterface.orElse(null)); - if (getInterfaceEither.isRight()) { - return Either.right(getInterfaceEither.right().value()); + Optional optionalInterface = InterfaceOperationUtils + .getInterfaceDefinitionFromComponentByInterfaceId( + storedComponent, interfaceId); + if (!optionalInterface.isPresent()) { + return Either.right( + componentsUtils.getResponseFormat(ActionStatus.INTERFACE_NOT_FOUND_IN_COMPONENT, interfaceId)); } - InterfaceDefinition interfaceDefinition = getInterfaceEither.left().value(); - - Either getOperationEither = getOperationFromInterfaceDef(storedComponent, interfaceDefinition, interfaceOperationToGet); - if (getOperationEither.isRight()){ - return Either.right(getOperationEither.right().value()); + InterfaceDefinition interfaceDefinition = optionalInterface.get(); + + for (String operationId : operationsToGet) { + Optional> optionalOperation = + InterfaceOperationUtils.getOperationFromInterfaceDefinition(interfaceDefinition, operationId); + if (!optionalOperation.isPresent()) { + return Either.right(componentsUtils.getResponseFormat(ActionStatus.INTERFACE_OPERATION_NOT_FOUND, + storedComponent.getUniqueId())); + } } titanDao.commit(); - return Either.left(getOperationEither.left().value()); - } - catch (Exception e){ + interfaceDefinition.getOperations().keySet().removeIf(key -> !(operationsToGet.contains(key))); + return Either.left(Collections.singletonList(interfaceDefinition)); + } catch (Exception e) { LOGGER.error(EXCEPTION_OCCURRED_DURING_INTERFACE_OPERATION, "get", e); titanDao.rollback(); - return Either.right(componentsUtils.getResponseFormat(ActionStatus.INTERFACE_OPERATION_NOT_FOUND, componentId)); - } - finally { + return Either.right( + componentsUtils.getResponseFormat(ActionStatus.INTERFACE_OPERATION_NOT_FOUND, componentId)); + } finally { if (lockResult.isLeft() && lockResult.left().value()) { - graphLockOperation.unlockComponent(storedComponent.getUniqueId(), NodeTypeEnum.getByNameIgnoreCase(storedComponent.getComponentType().getValue())); + graphLockOperation.unlockComponent(storedComponent.getUniqueId(), + NodeTypeEnum.getByNameIgnoreCase(storedComponent.getComponentType().getValue())); } } } - private Either getInterfaceDefinition(org.openecomp.sdc.be.model.Component component, InterfaceDefinition interfaceDef) { - if (interfaceDef != null){ - return Either.left(interfaceDef); - } else { - InterfaceDefinition interfaceDefinition = new InterfaceDefinition(); - interfaceDefinition.setToscaResourceName(InterfaceUtils.createInterfaceToscaResourceName(component.getName())); - Either interfaceCreateEither = interfaceOperation.addInterface(component.getUniqueId(), interfaceDefinition); - if (interfaceCreateEither.isRight()){ - StorageOperationStatus sValue = interfaceCreateEither.right().value(); - LOGGER.error("Failed to get interface from component {}. Response is {}", component.getName(), sValue); - return Either.right(componentsUtils.getResponseFormat(componentsUtils.convertFromStorageResponse(sValue, component.getComponentType()), "")); - } - return Either.left(interfaceCreateEither.left().value()); - } + public Either, ResponseFormat> createInterfaceOperation(String componentId, + List interfaceDefinitions, User user, boolean lock) { + return createOrUpdateInterfaceOperation(componentId, interfaceDefinitions, user, false, + CREATE_INTERFACE_OPERATION, lock); } - public Either createInterfaceOperation(String componentId, Operation operation, User user, boolean lock) { - return createOrUpdateInterfaceOperation(componentId, operation, user, false, CREATE_INTERFACE_OPERATION, lock); - } - - public Either updateInterfaceOperation(String componentId, Operation operation, User user, boolean lock) { - return createOrUpdateInterfaceOperation(componentId, operation, user, true, UPDATE_INTERFACE_OPERATION, lock); - } + private Either, ResponseFormat> createOrUpdateInterfaceOperation(String componentId, + List interfaceDefinitions, User user, boolean isUpdate, String errorContext, + boolean lock) { + validateUserExists(user.getUserId(), errorContext, true); - private Either createOrUpdateInterfaceOperation(String componentId, Operation operation, User user, boolean isUpdate, String errorContext, boolean lock) { Either componentEither = getComponentDetails(componentId); - if (componentEither.isRight()){ + if (componentEither.isRight()) { return Either.right(componentEither.right().value()); } org.openecomp.sdc.be.model.Component storedComponent = componentEither.left().value(); - validateUserExists(user.getUserId(), errorContext, true); - Either interfaceOperationValidationResponseEither = interfaceOperationValidation - .validateInterfaceOperations(Collections.singletonList(operation), storedComponent, isUpdate); - if(interfaceOperationValidationResponseEither.isRight()) { - return Either.right(interfaceOperationValidationResponseEither.right().value()); - } Either lockResult = lockComponentResult(lock, storedComponent, errorContext); if (lockResult.isRight()) { return Either.right(lockResult.right().value()); } + Either, ResponseFormat> interfaceLifecycleTypes = + getAllInterfaceLifecycleTypes(); + if (interfaceLifecycleTypes.isRight()) { + return Either.right(interfaceLifecycleTypes.right().value()); + } + try { - Optional optionalInterface = InterfaceUtils.getInterfaceDefinitionFromToscaName(storedComponent.getInterfaces().values(), storedComponent.getName()); - Either getInterfaceEither = getInterfaceDefinition(storedComponent, optionalInterface.orElse(null)); - if (getInterfaceEither.isRight()) { - return Either.right(getInterfaceEither.right().value()); - } - InterfaceDefinition interfaceDefinition = getInterfaceEither.left().value(); + List interfacesCollection = new ArrayList<>(); + Map operationsCollection = new HashMap<>(); + for (InterfaceDefinition inputInterfaceDefinition : interfaceDefinitions) { + Optional optionalInterface = + InterfaceOperationUtils.getInterfaceDefinitionFromComponentByInterfaceType( + storedComponent, inputInterfaceDefinition.getType()); + Either interfaceOperationValidationResponseEither = + interfaceOperationValidation + .validateInterfaceOperations(inputInterfaceDefinition, storedComponent, + optionalInterface.orElse(null), interfaceLifecycleTypes.left().value(), + isUpdate); + if (interfaceOperationValidationResponseEither.isRight()) { + return Either.right(interfaceOperationValidationResponseEither.right().value()); + } - Either result; - if(!isUpdate){ - initNewOperation(operation); - result = interfaceOperation.addInterfaceOperation(componentId, interfaceDefinition, operation); - } - else { - Either getOperationEither = getOperationFromInterfaceDef(storedComponent, interfaceDefinition, operation.getUniqueId()); - if (getOperationEither.isRight()){ - return Either.right(getOperationEither.right().value()); + Map operationsToAddOrUpdate = inputInterfaceDefinition.getOperationsMap(); + operationsCollection.putAll(operationsToAddOrUpdate); + inputInterfaceDefinition.getOperations().clear(); + + Either getInterfaceEither = + getOrCreateInterfaceDefinition(storedComponent, inputInterfaceDefinition, + optionalInterface.orElse(null)); + if (getInterfaceEither.isRight()) { + return Either.right(getInterfaceEither.right().value()); } - updateExistingOperation(operation, getOperationEither.left().value().getImplementation().getArtifactUUID()); - result = interfaceOperation.updateInterfaceOperation(componentId, interfaceDefinition, operation); + InterfaceDefinition interfaceDef = getInterfaceEither.left().value(); + + updateOperationInputDefs(storedComponent, operationsToAddOrUpdate.values()); + + for (Operation operation : operationsToAddOrUpdate.values()) { + if (!isUpdate) { + addOperationToInterface(interfaceDef, operation); + } else { + Optional> optionalOperation = + InterfaceOperationUtils.getOperationFromInterfaceDefinition(interfaceDef, + operation.getUniqueId()); + if (!optionalOperation.isPresent()) { + titanDao.rollback(); + return Either.right(componentsUtils + .getResponseFormat(ActionStatus.INTERFACE_OPERATION_NOT_FOUND, + storedComponent.getUniqueId())); + } + + Operation storedOperation = optionalOperation.get().getValue(); + String artifactUuId = storedOperation.getImplementation().getArtifactUUID(); + Either artifactCount = + artifactCassandraDao.getCountOfArtifactById(artifactUuId); + if (artifactCount.isLeft()) { + CassandraOperationStatus cassandraStatus = + artifactCassandraDao.deleteArtifact(artifactUuId); + if (cassandraStatus != CassandraOperationStatus.OK) { + titanDao.rollback(); + ResponseFormat responseFormatByArtifactId = + componentsUtils.getResponseFormatByArtifactId( + componentsUtils.convertFromStorageResponse( + componentsUtils.convertToStorageOperationStatus( + cassandraStatus)), + storedOperation.getImplementation().getArtifactDisplayName()); + return Either.right(responseFormatByArtifactId); + } + } + updateOperationOnInterface(interfaceDef, operation, artifactUuId); + } + } + interfacesCollection.add(interfaceDef); } - if (result.isRight()) { + Either, StorageOperationStatus> addCreateOperationEither = + interfaceOperation.updateInterfaces(storedComponent.getUniqueId(), interfacesCollection); + if (addCreateOperationEither.isRight()) { titanDao.rollback(); - LOGGER.debug("Failed to addOrUpdate interface operation on component {}. Response is {}", storedComponent.getName(), result.right().value()); - return Either.right(componentsUtils.getResponseFormat(componentsUtils.convertFromStorageResponse(result.right().value(), storedComponent.getComponentType()))); + return Either.right(componentsUtils.getResponseFormat(componentsUtils.convertFromStorageResponse( + addCreateOperationEither.right().value(), storedComponent.getComponentType()))); } titanDao.commit(); - return Either.left(result.left().value()); - } - catch (Exception e) { + interfacesCollection.forEach(interfaceDefinition -> interfaceDefinition.getOperations().entrySet().removeIf( + entry -> !operationsCollection.values().stream().map(OperationDataDefinition::getName) + .collect(Collectors.toList()).contains(entry.getValue().getName()))); + return Either.left(interfacesCollection); + } catch (Exception e) { titanDao.rollback(); LOGGER.error(EXCEPTION_OCCURRED_DURING_INTERFACE_OPERATION, "addOrUpdate", e); return Either.right(componentsUtils.getResponseFormat(ActionStatus.GENERAL_ERROR)); - } - finally { + } finally { if (lockResult.isLeft() && lockResult.left().value()) { - graphLockOperation.unlockComponent(storedComponent.getUniqueId(), NodeTypeEnum.getByNameIgnoreCase(storedComponent.getComponentType().getValue())); + graphLockOperation.unlockComponent(storedComponent.getUniqueId(), + NodeTypeEnum.getByNameIgnoreCase(storedComponent.getComponentType().getValue())); } } } - private Either getComponentDetails(String componentId){ - Either componentStorageOperationStatusEither = toscaOperationFacade.getToscaElement(componentId); - if (componentStorageOperationStatusEither.isRight()) { - StorageOperationStatus errorStatus = componentStorageOperationStatusEither.right().value(); - LOGGER.error("Failed to fetch component information by component id {}, Response is {}", componentId, errorStatus); - return Either.right(componentsUtils.getResponseFormat(componentsUtils.convertFromStorageResponse(errorStatus))); - } - return Either.left(componentStorageOperationStatusEither.left().value()); - } + public Either, ResponseFormat> getAllInterfaceLifecycleTypes() { - private Either getOperationFromInterfaceDef( - org.openecomp.sdc.be.model.Component component, InterfaceDefinition interfaceDefinition, String operationToFetch) { - Optional> operationMap = interfaceDefinition.getOperationsMap().entrySet().stream() - .filter(entry -> entry.getValue().getUniqueId().equals(operationToFetch)).findAny(); - if (!operationMap.isPresent()) { - LOGGER.error("Failed to get interface operation from component {}. Response is {}", component.getUniqueId(), ActionStatus.INTERFACE_OPERATION_NOT_FOUND); - return Either.right(componentsUtils.getResponseFormat(ActionStatus.INTERFACE_OPERATION_NOT_FOUND, component.getUniqueId())); + Either, StorageOperationStatus> interfaceLifecycleTypes = + interfaceLifecycleTypeOperation.getAllInterfaceLifecycleTypes(); + if (interfaceLifecycleTypes.isRight()) { + return Either.right(componentsUtils.getResponseFormat(ActionStatus.INTERFACE_LIFECYCLE_TYPES_NOT_FOUND)); } - return Either.left(operationMap.get().getValue()); - } - - private void initNewOperation(Operation operation){ - ArtifactDefinition artifactDefinition = new ArtifactDefinition(); - String artifactUUID = UUID.randomUUID().toString(); - artifactDefinition.setArtifactUUID(artifactUUID); - artifactDefinition.setUniqueId(artifactUUID); - artifactDefinition.setArtifactType(ArtifactTypeEnum.WORKFLOW.getType()); - artifactDefinition.setArtifactGroupType(ArtifactGroupTypeEnum.DEPLOYMENT); - operation.setUniqueId(UUID.randomUUID().toString()); - operation.setImplementation(artifactDefinition); - } + interfaceLifecycleTypes.left().value().values().forEach(id -> id.setOperations( + id.getOperations().keySet().stream().collect(Collectors.toMap(key -> key.replaceFirst( + id.getUniqueId() + ".", ""), i -> id.getOperations().get(i))))); - private void updateExistingOperation(Operation operation, String artifactUUID){ - ArtifactDefinition artifactDefinition = new ArtifactDefinition(); - artifactDefinition.setArtifactUUID(artifactUUID); - artifactDefinition.setUniqueId(artifactUUID); - artifactDefinition.setArtifactType(ArtifactTypeEnum.WORKFLOW.getType()); - artifactDefinition.setArtifactGroupType(ArtifactGroupTypeEnum.DEPLOYMENT); - operation.setImplementation(artifactDefinition); + return Either.left(interfaceLifecycleTypes.left().value()); } - private Either lockComponentResult(boolean lock, org.openecomp.sdc.be.model.Component component, String action){ - if (lock) { - Either lockResult = lockComponent(component.getUniqueId(), component, action); - if (lockResult.isRight()) { - LOGGER.debug(FAILED_TO_LOCK_COMPONENT_RESPONSE_IS, component.getName(), lockResult.right().value().getFormattedMessage()); + private Either getOrCreateInterfaceDefinition( + org.openecomp.sdc.be.model.Component component, InterfaceDefinition interfaceDefinition, + InterfaceDefinition storedInterfaceDef) { + if (storedInterfaceDef != null) { + return Either.left(storedInterfaceDef); + } else { + interfaceDefinition.setUniqueId(UUID.randomUUID().toString()); + interfaceDefinition.setToscaResourceName(interfaceDefinition.getType()); + Either, StorageOperationStatus> interfaceCreateEither = + interfaceOperation.addInterfaces(component.getUniqueId(), + Collections.singletonList(interfaceDefinition)); + if (interfaceCreateEither.isRight()) { titanDao.rollback(); - return Either.right(lockResult.right().value()); + return Either.right(componentsUtils.getResponseFormat(componentsUtils.convertFromStorageResponse( + interfaceCreateEither.right().value(), component.getComponentType()))); } + return Either.left(interfaceCreateEither.left().value().get(0)); } - return Either.left(true); } - public Either validateComponentNameAndUpdateInterfaces(org.openecomp.sdc.be.model.Component oldComponent, - org.openecomp.sdc.be.model.Component newComponent) { - if(!oldComponent.getName().equals(newComponent.getName()) ) { - Collection interfaceDefinitionListFromToscaName = InterfaceUtils - .getInterfaceDefinitionListFromToscaName(oldComponent.getInterfaces().values(), - oldComponent.getName()); - for (InterfaceDefinition interfaceDefinition : interfaceDefinitionListFromToscaName) { - - Either interfaceDefinitionResponseEither = updateInterfaceDefinition(oldComponent, - newComponent, interfaceDefinition); - if(interfaceDefinitionResponseEither.isRight()) { - return Either.right(interfaceDefinitionResponseEither.right().value()); - } - } - } - return Either.left(Boolean.TRUE); + private void updateOperationInputDefs(org.openecomp.sdc.be.model.Component component, + Collection interfaceOperations) { + interfaceOperations.stream().filter(operation -> Objects.nonNull(operation.getInputs())).forEach( + operation -> operation.getInputs().getListToscaDataDefinition().forEach( + inp -> component.getInputs().stream().filter(in -> inp.getInputId().equals(in.getUniqueId())) + .forEach(in -> { + inp.setDefaultValue(in.getDefaultValue()); + inp.setValue(in.getValue()); + inp.setSchema(in.getSchema()); + }))); } - private Either updateInterfaceDefinition(org.openecomp.sdc.be.model.Component oldComponent, - org.openecomp.sdc.be.model.Component newComponent, - InterfaceDefinition interfaceDefinition) { - InterfaceUtils.createInterfaceToscaResourceName(newComponent.getName()); - interfaceDefinition.setToscaResourceName(InterfaceUtils - .createInterfaceToscaResourceName(newComponent.getName())); - try { - Either interfaceUpdate = interfaceOperation - .updateInterface(oldComponent.getUniqueId(), interfaceDefinition); - if (interfaceUpdate.isRight()) { - LOGGER.error("Failed to Update interface {}. Response is {}. ", newComponent.getName(), interfaceUpdate.right().value()); - titanDao.rollback(); - return Either.right(componentsUtils.getResponseFormat(componentsUtils.convertFromStorageResponse(interfaceUpdate.right().value(), ComponentTypeEnum.RESOURCE))); - } - } catch (Exception e) { - LOGGER.error("Exception occurred during update interface toscaResourceName : {}", e); - titanDao.rollback(); - return Either.right(componentsUtils.getResponseFormat(ActionStatus.GENERAL_ERROR)); - } - return Either.left( interfaceDefinition); + + private void addOperationToInterface(InterfaceDefinition interfaceDefinition, Operation interfaceOperation) { + interfaceOperation.setUniqueId(UUID.randomUUID().toString()); + interfaceOperation.setImplementation(createArtifactDefinition(UUID.randomUUID().toString())); + interfaceDefinition.getOperations() + .put(interfaceOperation.getUniqueId(), new OperationDataDefinition(interfaceOperation)); } - public Either, ResponseFormat> getAllInterfaceLifecycleTypes() { + private void updateOperationOnInterface(InterfaceDefinition interfaceDefinition, Operation interfaceOperation, + String artifactUuId) { + interfaceOperation.setImplementation(createArtifactDefinition(artifactUuId)); + interfaceDefinition.getOperations() + .put(interfaceOperation.getUniqueId(), new OperationDataDefinition(interfaceOperation)); + } - Either, StorageOperationStatus> interfaceLifecycleTypes = interfaceLifecycleOperation.getAllInterfaceLifecycleTypes(); - if(interfaceLifecycleTypes.isRight()) { - return Either.right(componentsUtils.getResponseFormat(ActionStatus.INTERFACE_LIFECYCLE_TYPES_NOT_FOUND)); - } - interfaceLifecycleTypes.left().value().values().stream().forEach( - id -> id.setOperations(id.getOperations().keySet().stream().collect(Collectors.toMap(key -> key.replaceFirst(id.getUniqueId()+".",""), i -> id.getOperations().get(i))))); + private ArtifactDefinition createArtifactDefinition(String artifactUuId) { + ArtifactDefinition artifactDefinition = new ArtifactDefinition(); + artifactDefinition.setArtifactUUID(artifactUuId); + artifactDefinition.setUniqueId(artifactUuId); + artifactDefinition.setArtifactType(ArtifactTypeEnum.WORKFLOW.getType()); + artifactDefinition.setArtifactGroupType(ArtifactGroupTypeEnum.DEPLOYMENT); + return artifactDefinition; + } - return Either.left(interfaceLifecycleTypes.left().value()); + public Either, ResponseFormat> updateInterfaceOperation(String componentId, + List interfaceDefinitions, User user, boolean lock) { + return createOrUpdateInterfaceOperation(componentId, interfaceDefinitions, user, true, + UPDATE_INTERFACE_OPERATION, lock); } + } diff --git a/catalog-be/src/main/java/org/openecomp/sdc/be/components/impl/ResourceBusinessLogic.java b/catalog-be/src/main/java/org/openecomp/sdc/be/components/impl/ResourceBusinessLogic.java index 7917a0aa5d..4e842928ef 100644 --- a/catalog-be/src/main/java/org/openecomp/sdc/be/components/impl/ResourceBusinessLogic.java +++ b/catalog-be/src/main/java/org/openecomp/sdc/be/components/impl/ResourceBusinessLogic.java @@ -3984,14 +3984,6 @@ public class ResourceBusinessLogic extends ComponentBusinessLogic { newResource.setDerivedFrom(null); } - Either validateAndUpdateInterfacesEither = - interfaceOperationBusinessLogic.validateComponentNameAndUpdateInterfaces(currentResource, newResource); - if (validateAndUpdateInterfacesEither.isRight()) { - log.error("failed to validate and update Interfaces"); - rollbackNeeded = true; - throw new ComponentException(validateAndUpdateInterfacesEither.right().value()); - } - Either dataModelResponse = updateResourceMetadata(resourceIdToUpdate, newResource, user, currentResource, false, true); if (dataModelResponse.isRight()) { 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 e85afdc48f..8d4f896d47 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 @@ -518,11 +518,7 @@ public class ServiceBusinessLogic extends ComponentBusinessLogic { log.info("Restricted operation for user: {}, on service: {}", user.getUserId(), currentService.getCreatorUserId()); return Either.right(componentsUtils.getResponseFormat(ActionStatus.RESTRICTED_OPERATION)); } - Either validateAndUpdateInterfacesEither = interfaceOperationBusinessLogic.validateComponentNameAndUpdateInterfaces(currentService, serviceUpdate); - if (validateAndUpdateInterfacesEither.isRight()) { - log.info("failed to validate and update Interfaces on service {}", currentService.getCreatorUserId()); - return Either.right(validateAndUpdateInterfacesEither.right().value()); - } + Either validationRsponse = validateAndUpdateServiceMetadata(user, currentService, serviceUpdate); if (validationRsponse.isRight()) { log.info("service update metadata: validations field."); diff --git a/catalog-be/src/main/java/org/openecomp/sdc/be/components/utils/InterfaceOperationUtils.java b/catalog-be/src/main/java/org/openecomp/sdc/be/components/utils/InterfaceOperationUtils.java new file mode 100644 index 0000000000..0233711a89 --- /dev/null +++ b/catalog-be/src/main/java/org/openecomp/sdc/be/components/utils/InterfaceOperationUtils.java @@ -0,0 +1,64 @@ +/* + * 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.utils; + +import java.util.Map; +import java.util.Optional; +import org.apache.commons.collections.MapUtils; +import org.openecomp.sdc.be.model.Component; +import org.openecomp.sdc.be.model.InterfaceDefinition; +import org.openecomp.sdc.be.model.Operation; + +public class InterfaceOperationUtils { + + private InterfaceOperationUtils() { + } + + public static Optional getInterfaceDefinitionFromComponentByInterfaceType(Component component, + String interfaceType) { + if (MapUtils.isEmpty(component.getInterfaces())) { + return Optional.empty(); + } + return component.getInterfaces().values().stream() + .filter(interfaceDefinition -> interfaceDefinition.getType() != null && interfaceDefinition + .getType() + .equals(interfaceType)) + .findAny(); + } + + public static Optional getInterfaceDefinitionFromComponentByInterfaceId(Component component, + String interfaceId) { + if (MapUtils.isEmpty(component.getInterfaces())) { + return Optional.empty(); + } + return component.getInterfaces().values().stream() + .filter(interfaceDefinition -> interfaceDefinition.getUniqueId() != null && interfaceDefinition + .getUniqueId() + .equals(interfaceId)) + .findAny(); + } + + public static Optional> getOperationFromInterfaceDefinition( + InterfaceDefinition interfaceDefinition, String operationId) { + if (MapUtils.isEmpty(interfaceDefinition.getOperationsMap())) { + return Optional.empty(); + } + return interfaceDefinition.getOperationsMap().entrySet().stream() + .filter(entry -> entry.getValue().getUniqueId().equals(operationId)).findAny(); + } + +} diff --git a/catalog-be/src/main/java/org/openecomp/sdc/be/components/validation/InterfaceOperationValidation.java b/catalog-be/src/main/java/org/openecomp/sdc/be/components/validation/InterfaceOperationValidation.java index 7b650e4fad..c80f57486d 100644 --- a/catalog-be/src/main/java/org/openecomp/sdc/be/components/validation/InterfaceOperationValidation.java +++ b/catalog-be/src/main/java/org/openecomp/sdc/be/components/validation/InterfaceOperationValidation.java @@ -16,6 +16,7 @@ package org.openecomp.sdc.be.components.validation; +import fj.data.Either; import java.util.Collection; import java.util.HashMap; import java.util.HashSet; @@ -25,16 +26,11 @@ import java.util.Objects; import java.util.Optional; import java.util.Set; import java.util.regex.Pattern; -import java.util.stream.Collectors; - -import fj.data.Either; +import java.util.stream.Stream; import org.apache.commons.collections.CollectionUtils; -import org.apache.commons.collections.MapUtils; import org.apache.commons.lang.StringUtils; -import org.elasticsearch.common.Strings; import org.openecomp.sdc.be.components.impl.ResponseFormatManager; import org.openecomp.sdc.be.dao.api.ActionStatus; -import org.openecomp.sdc.be.datatypes.elements.ListDataDefinition; import org.openecomp.sdc.be.datatypes.elements.OperationInputDefinition; import org.openecomp.sdc.be.model.InputDefinition; import org.openecomp.sdc.be.model.InterfaceDefinition; @@ -47,272 +43,339 @@ import org.springframework.stereotype.Component; @Component("interfaceOperationValidation") public class InterfaceOperationValidation { - private static final String TYPE_VALIDATION_REGEX = "^[a-zA-Z]{1,200}$"; - private static final int DESCRIPTION_MAX_LENGTH = 200; + private static final String TYPE_VALIDATION_REGEX = "^[a-zA-Z0-9_]{1,200}$"; private static final Logger LOGGER = LoggerFactory.getLogger(InterfaceOperationValidation.class); - public Either validateInterfaceOperations( - Collection interfaceOperations, org.openecomp.sdc.be.model.Component component, boolean isUpdate) { + public Either validateInterfaceOperations(InterfaceDefinition inputInterfaceDefinition, + org.openecomp.sdc.be.model.Component component, InterfaceDefinition storedInterfaceDefinition, + Map globalInterfaceTypes, boolean isUpdate) { + + Either validateAllowedOperationCountOnLocalInterfaceType = + validateAllowedOperationCountOnLocalInterfaceType(inputInterfaceDefinition, storedInterfaceDefinition, + globalInterfaceTypes, isUpdate); + if (validateAllowedOperationCountOnLocalInterfaceType.isRight()) { + return validateAllowedOperationCountOnLocalInterfaceType; + } + + Either validateAllowedOperationsOnGlobalInterfaceType = + validateAllowedOperationsOnGlobalInterfaceType(inputInterfaceDefinition, globalInterfaceTypes); + if (validateAllowedOperationsOnGlobalInterfaceType.isRight()) { + return validateAllowedOperationsOnGlobalInterfaceType; + } - for(Operation interfaceOperation : interfaceOperations) { - Either interfaceOperationValidatorResponse = validateInterfaceOperation( - interfaceOperation, component, isUpdate); + Either validateOperationNameUniqueness = + validateOperationNameUniquenessInCollection(inputInterfaceDefinition.getOperationsMap().values()); + if (validateOperationNameUniqueness.isRight()) { + return validateOperationNameUniqueness; + } + + for (Operation interfaceOperation : inputInterfaceDefinition.getOperationsMap().values()) { + Either interfaceOperationValidatorResponse = + validateInterfaceOperation(interfaceOperation, storedInterfaceDefinition, component, isUpdate); if (interfaceOperationValidatorResponse.isRight()) { return interfaceOperationValidatorResponse; } } + return Either.left(Boolean.TRUE); } - private Either validateInterfaceOperation(Operation interfaceOperation, - org.openecomp.sdc.be.model.Component component, boolean isUpdate) { - ResponseFormatManager responseFormatManager = getResponseFormatManager(); + private Either validateAllowedOperationCountOnLocalInterfaceType( + InterfaceDefinition inputInterfaceDefinition, InterfaceDefinition storedInterfaceDefinition, + Map globalInterfaceTypes, boolean isUpdate) { + + boolean isInterfaceTypeExistInGlobalType = + globalInterfaceTypes.values().stream().map(InterfaceDefinition::getType) + .anyMatch(type -> type.equalsIgnoreCase(inputInterfaceDefinition.getType())); + if (!isInterfaceTypeExistInGlobalType + && (inputInterfaceDefinition.getOperations().size() > 1 + || (!isUpdate && storedInterfaceDefinition != null + && storedInterfaceDefinition.getType() + .equalsIgnoreCase(inputInterfaceDefinition.getType())))) { + return Either.right(getResponseFormatManager() + .getResponseFormat(ActionStatus.INTERFACE_OPERATION_INVALID_FOR_LOCAL_TYPE, + inputInterfaceDefinition.getType())); + } - Either interfaceOperationTypeResponse = isInterfaceOperationTypeValid(interfaceOperation, - responseFormatManager, component, isUpdate); - if (interfaceOperationTypeResponse.isRight()) { - return Either.right(interfaceOperationTypeResponse.right().value()); + return Either.left(Boolean.TRUE); + } + + private Either validateAllowedOperationsOnGlobalInterfaceType( + InterfaceDefinition interfaceDefinition, Map globalInterfaceTypes) { + + if (globalInterfaceTypes != null) { + boolean isOperationValidOnGlobalInterfaceType = + Stream.of(interfaceDefinition) + .filter(interfaceDef -> globalInterfaceTypes.values().stream().anyMatch( + interfaceDef1 -> interfaceDef1.getType().equalsIgnoreCase(interfaceDef.getType()))) + .flatMap(interfaceDef -> interfaceDef.getOperationsMap().values().stream() + .map(Operation::getName)) + .allMatch(operationName -> globalInterfaceTypes.values().stream() + .flatMap(interfaceDef -> interfaceDef.getOperationsMap() + .keySet().stream()) + .anyMatch(opName -> + opName.equalsIgnoreCase( + operationName))); + if (!isOperationValidOnGlobalInterfaceType) { + return Either.right(getResponseFormatManager() + .getResponseFormat(ActionStatus.INTERFACE_OPERATION_INVALID_FOR_GLOBAL_TYPE, + interfaceDefinition.getType())); + } } + return Either.left(Boolean.TRUE); + } - Either descriptionResponseEither = isValidDescription(responseFormatManager, - interfaceOperation.getDescription()); - if (descriptionResponseEither.isRight()) { - return Either.right(descriptionResponseEither.right().value()); + private Either validateOperationNameUniquenessInCollection( + Collection operationList) { + HashSet operationNames = new HashSet<>(); + for (Operation operation : operationList) { + if (!operationNames.add(operation.getName())) { + return Either.right(getResponseFormatManager() + .getResponseFormat(ActionStatus.INTERFACE_OPERATION_NAME_ALREADY_IN_USE, + operation.getName())); + } } + return Either.left(Boolean.TRUE); + } - Either inputPropertyExistInComponent = validateInputPropertyExistInComponent(interfaceOperation, - component.getInputs(), responseFormatManager); - if(inputPropertyExistInComponent.isRight()) { - return Either.right(inputPropertyExistInComponent.right().value()); + private Either validateInterfaceOperation(Operation interfaceOperation, + InterfaceDefinition interfaceDefinition, org.openecomp.sdc.be.model.Component component, boolean isUpdate) { + ResponseFormatManager responseFormatManager = getResponseFormatManager(); + Either interfaceOperationTypeResponse = + isInterfaceOperationTypeValid(interfaceOperation, responseFormatManager, interfaceDefinition, isUpdate); + if (interfaceOperationTypeResponse.isRight()) { + return Either.right(interfaceOperationTypeResponse.right().value()); } - Either inputParametersResponse = validateInputParameters(interfaceOperation, - responseFormatManager); - if(inputParametersResponse.isRight()) { - return Either.right(inputParametersResponse.right().value()); + if (null != interfaceOperation.getInputs()) { + Either inputParametersResponse = + validateInputParameters(interfaceOperation, responseFormatManager); + if (inputParametersResponse.isRight()) { + return Either.right(inputParametersResponse.right().value()); + } + + Either inputPropertyExistInComponent = + validateInputPropertyExistInComponent(interfaceOperation, component, responseFormatManager); + if (inputPropertyExistInComponent.isRight()) { + return Either.right(inputPropertyExistInComponent.right().value()); + + } } - Either outputParametersResponse = validateOutputParameters(interfaceOperation, - responseFormatManager); - if(outputParametersResponse.isRight()) { - return Either.right(outputParametersResponse.right().value()); + if (null != interfaceOperation.getOutputs()) { + Either outputParametersResponse = + validateOutputParameters(interfaceOperation, responseFormatManager); + if (outputParametersResponse.isRight()) { + return Either.right(outputParametersResponse.right().value()); + } } return Either.left(Boolean.TRUE); } + protected ResponseFormatManager getResponseFormatManager() { + return ResponseFormatManager.getInstance(); + } + private Either isInterfaceOperationTypeValid(Operation interfaceOperation, - ResponseFormatManager responseFormatManager, - org.openecomp.sdc.be.model.Component component, boolean isUpdate) { + ResponseFormatManager responseFormatManager, InterfaceDefinition interfaceDefinition, boolean isUpdate) { Either operationTypeEmptyEither = - isOperationTypeEmpty(responseFormatManager, interfaceOperation.getName()); + isOperationTypeEmpty(responseFormatManager, interfaceOperation.getName()); if (operationTypeEmptyEither.isRight()) { return Either.right(operationTypeEmptyEither.right().value()); } Either operationTypeRegexValidationResponse = - isOperationTypeRegexValid(responseFormatManager, interfaceOperation.getName()); + isOperationTypeRegexValid(responseFormatManager, interfaceOperation.getName()); if (operationTypeRegexValidationResponse.isRight()) { return Either.right(operationTypeRegexValidationResponse.right().value()); } - Either operationTypeUniqueResponse = validateOperationTypeUnique(interfaceOperation, - component, isUpdate ); - if(operationTypeUniqueResponse.isRight()) { + Either operationTypeUniqueResponse = + validateOperationTypeUnique(interfaceOperation, interfaceDefinition, isUpdate); + if (operationTypeUniqueResponse.isRight()) { return Either.right(operationTypeUniqueResponse.right().value()); } if (!operationTypeUniqueResponse.left().value()) { LOGGER.error("Interface Operation type {} already in use ", interfaceOperation.getName()); - ResponseFormat errorResponse = responseFormatManager.getResponseFormat(ActionStatus - .INTERFACE_OPERATION_NAME_ALREADY_IN_USE, interfaceOperation.getName()); + ResponseFormat errorResponse = responseFormatManager.getResponseFormat( + ActionStatus.INTERFACE_OPERATION_NAME_ALREADY_IN_USE, interfaceOperation.getName()); return Either.right(errorResponse); } return Either.left(Boolean.TRUE); } - private Either isOperationTypeRegexValid(ResponseFormatManager responseFormatManager, - String operationType) { - if (!isValidOperationType(operationType)) { - LOGGER.error("Interface Operation type {} is invalid, Operation type should not contain" + - "Special character, space, numbers and should not be greater than 200 characters", operationType); - ResponseFormat errorResponse = responseFormatManager.getResponseFormat(ActionStatus - .INTERFACE_OPERATION_NAME_INVALID, operationType); - return Either.right(errorResponse); + private Either validateInputParameters(Operation interfaceOperation, + ResponseFormatManager responseFormatManager) { + if (isInputParameterNameEmpty(interfaceOperation)) { + LOGGER.error("Interface operation input parameter name can't be empty"); + ResponseFormat inputResponse = + responseFormatManager.getResponseFormat(ActionStatus.INTERFACE_OPERATION_INPUT_NAME_MANDATORY); + return Either.right(inputResponse); + } + + Either> validateInputParametersUniqueResponse = + isInputParametersUnique(interfaceOperation); + if (validateInputParametersUniqueResponse.isRight()) { + LOGGER.error("Interface operation input parameter names {} already in use", + validateInputParametersUniqueResponse.right().value()); + ResponseFormat inputResponse = responseFormatManager.getResponseFormat( + ActionStatus.INTERFACE_OPERATION_INPUT_NAME_ALREADY_IN_USE, + validateInputParametersUniqueResponse.right().value().toString()); + return Either.right(inputResponse); + } + return Either.left(Boolean.TRUE); + } + + private Either validateInputPropertyExistInComponent(Operation operation, + org.openecomp.sdc.be.model.Component component, ResponseFormatManager responseFormatManager) { + + List inputListToscaDataDefinition = + operation.getInputs().getListToscaDataDefinition(); + for (OperationInputDefinition inputDefinition : inputListToscaDataDefinition) { + if (!validateInputExistsInComponent(inputDefinition, component.getInputs())) { + String missingPropertyName = inputDefinition.getInputId().contains(".") + ? inputDefinition.getInputId().substring( + inputDefinition.getInputId().indexOf('.') + 1) + : inputDefinition.getInputId(); + LOGGER.error("Interface operation input property {} not found in component input properties", + missingPropertyName); + ResponseFormat inputResponse = responseFormatManager.getResponseFormat( + ActionStatus.INTERFACE_OPERATION_INPUT_PROPERTY_NOT_FOUND_IN_COMPONENT, missingPropertyName, + component.getComponentType().getValue()); + return Either.right(inputResponse); + } + } + return Either.left(Boolean.TRUE); + } + + private Either validateOutputParameters(Operation interfaceOperation, + ResponseFormatManager responseFormatManager) { + if (isOutputParameterNameEmpty(interfaceOperation)) { + LOGGER.error("Interface operation output parameter name can't be empty"); + ResponseFormat inputResponse = + responseFormatManager.getResponseFormat(ActionStatus.INTERFACE_OPERATION_OUTPUT_NAME_MANDATORY); + return Either.right(inputResponse); + } + + Either> validateOutputParametersUniqueResponse = + isOutputParametersUnique(interfaceOperation); + if (validateOutputParametersUniqueResponse.isRight()) { + LOGGER.error("Interface operation output parameter names {} already in use", + validateOutputParametersUniqueResponse.right().value()); + ResponseFormat inputResponse = responseFormatManager.getResponseFormat( + ActionStatus.INTERFACE_OPERATION_OUTPUT_NAME_ALREADY_IN_USE, + validateOutputParametersUniqueResponse.right().value().toString()); + return Either.right(inputResponse); } return Either.left(Boolean.TRUE); } private Either isOperationTypeEmpty(ResponseFormatManager responseFormatManager, - String operationType) { + String operationType) { if (StringUtils.isEmpty(operationType)) { LOGGER.error("Interface Operation type is mandatory"); - ResponseFormat errorResponse = responseFormatManager.getResponseFormat(ActionStatus - .INTERFACE_OPERATION_NAME_MANDATORY); + ResponseFormat errorResponse = + responseFormatManager.getResponseFormat(ActionStatus.INTERFACE_OPERATION_NAME_MANDATORY); return Either.right(errorResponse); } return Either.left(Boolean.TRUE); } - private Either isValidDescription(ResponseFormatManager responseFormatManager, - String description) { - if (!Strings.isNullOrEmpty(description) && description.length() > DESCRIPTION_MAX_LENGTH) { - LOGGER.error("Interface Operation description {} is invalid, maximum 200 characters allowed", description); - ResponseFormat errorResponse = responseFormatManager.getResponseFormat(ActionStatus - .INTERFACE_OPERATION_DESCRIPTION_MAX_LENGTH, description); + private Either isOperationTypeRegexValid(ResponseFormatManager responseFormatManager, + String operationType) { + if (!isValidOperationType(operationType)) { + LOGGER.error("Interface Operation type {} is invalid, Operation type should not contain" + + "Special character, space, numbers and should not be greater than 200 characters", + operationType); + ResponseFormat errorResponse = responseFormatManager + .getResponseFormat(ActionStatus.INTERFACE_OPERATION_NAME_INVALID, + operationType); return Either.right(errorResponse); } return Either.left(Boolean.TRUE); } - private boolean isValidOperationType(String operationType) { - return Pattern.matches(TYPE_VALIDATION_REGEX, operationType); - } - - private Either validateOperationTypeUnique( - Operation interfaceOperation, - org.openecomp.sdc.be.model.Component component, - boolean isUpdate) { + private Either validateOperationTypeUnique(Operation interfaceOperation, + InterfaceDefinition interfaceDefinition, boolean isUpdate) { boolean isOperationTypeUnique = false; - Map interfaceDefinitionMap = component.getInterfaces(); - if(interfaceDefinitionMap.isEmpty()){ - return Either.left(true); - } - - Collection allOperations = interfaceDefinitionMap.values().stream() - .filter(a -> MapUtils.isNotEmpty(a.getOperationsMap())) - .map(a -> a.getOperationsMap().values()).flatMap(Collection::stream) - .collect(Collectors.toList()); - if(CollectionUtils.isEmpty(allOperations)){ + if (interfaceDefinition == null || CollectionUtils.isEmpty(interfaceDefinition.getOperationsMap().values())) { return Either.left(true); } Map operationTypes = new HashMap<>(); - allOperations.forEach(operationType -> operationTypes.put(operationType.getUniqueId(), operationType.getName())); + interfaceDefinition.getOperationsMap().values() + .forEach(operationType -> operationTypes.put(operationType.getUniqueId(), operationType.getName())); - if (!operationTypes.values().contains(interfaceOperation.getName())){ + if (!operationTypes.values().contains(interfaceOperation.getName())) { isOperationTypeUnique = true; } - if (!isOperationTypeUnique && isUpdate){ - Optional id = operationTypes.entrySet().stream().filter(entry -> Objects.equals(entry.getValue(), interfaceOperation.getName())) - .map(Map.Entry::getKey).findAny(); - if(id.isPresent() && id.get().equalsIgnoreCase(interfaceOperation.getUniqueId())){ + if (!isOperationTypeUnique && isUpdate) { + Optional id = operationTypes.entrySet().stream().filter(entry -> Objects.equals(entry.getValue(), + interfaceOperation.getName())).map(Map.Entry::getKey).findAny(); + if (id.isPresent() && id.get().equalsIgnoreCase(interfaceOperation.getUniqueId())) { isOperationTypeUnique = true; } } return Either.left(isOperationTypeUnique); } - private Either validateInputParameters(Operation interfaceOperation, - ResponseFormatManager responseFormatManager) { - if (isInputParameterNameEmpty(interfaceOperation)) { - LOGGER.error("Interface operation input parameter name can't be empty"); - ResponseFormat inputResponse = responseFormatManager.getResponseFormat(ActionStatus.INTERFACE_OPERATION_INPUT_NAME_MANDATORY); - return Either.right(inputResponse); - } - Either> validateInputParametersUniqueResponse = isInputParametersUnique(interfaceOperation); - if(validateInputParametersUniqueResponse.isRight()) { - LOGGER.error("Interface operation input parameter names {} already in use", - validateInputParametersUniqueResponse.right().value()); - ResponseFormat inputResponse = responseFormatManager.getResponseFormat(ActionStatus - .INTERFACE_OPERATION_INPUT_NAME_ALREADY_IN_USE, validateInputParametersUniqueResponse.right().value().toString()); - return Either.right(inputResponse); - } - return Either.left(Boolean.TRUE); + private Boolean isInputParameterNameEmpty(Operation operationDataDefinition) { + return operationDataDefinition.getInputs().getListToscaDataDefinition().stream().anyMatch( + inputParam -> inputParam.getName() == null || inputParam.getName().trim().equals(StringUtils.EMPTY)); } - - private Either validateOutputParameters(Operation interfaceOperation, - ResponseFormatManager responseFormatManager) { - if (isOutputParameterNameEmpty(interfaceOperation)) { - LOGGER.error("Interface operation output parameter name can't be empty"); - ResponseFormat inputResponse = responseFormatManager.getResponseFormat(ActionStatus.INTERFACE_OPERATION_OUTPUT_NAME_MANDATORY); - return Either.right(inputResponse); - } - - Either> validateOutputParametersUniqueResponse = isOutputParametersUnique(interfaceOperation); - if(validateOutputParametersUniqueResponse.isRight()) { - LOGGER.error("Interface operation output parameter names {} already in use", - validateOutputParametersUniqueResponse.right().value()); - ResponseFormat inputResponse = responseFormatManager.getResponseFormat(ActionStatus - .INTERFACE_OPERATION_OUTPUT_NAME_ALREADY_IN_USE, validateOutputParametersUniqueResponse.right().value().toString()); - return Either.right(inputResponse); - } - return Either.left(Boolean.TRUE); - } private Either> isInputParametersUnique(Operation operationDataDefinition) { Set inputParamNamesSet = new HashSet<>(); Set duplicateParamNamesToReturn = new HashSet<>(); - operationDataDefinition.getInputs().getListToscaDataDefinition() - .forEach(inputParam -> { - if(!inputParamNamesSet.add(inputParam.getName().trim())) { - duplicateParamNamesToReturn.add(inputParam.getName().trim()); - } - }); - if(!duplicateParamNamesToReturn.isEmpty()) { + operationDataDefinition.getInputs().getListToscaDataDefinition().forEach(inputParam -> { + if (!inputParamNamesSet.add(inputParam.getName().trim())) { + duplicateParamNamesToReturn.add(inputParam.getName().trim()); + } + }); + if (!duplicateParamNamesToReturn.isEmpty()) { return Either.right(duplicateParamNamesToReturn); } return Either.left(Boolean.TRUE); } - private Either> isOutputParametersUnique(Operation operationDataDefinition) { - Set outputParamNamesSet = new HashSet<>(); - Set duplicateParamNamesToReturn = new HashSet<>(); - operationDataDefinition.getOutputs().getListToscaDataDefinition() - .forEach(outputParam -> { - if(!outputParamNamesSet.add(outputParam.getName().trim())) { - duplicateParamNamesToReturn.add(outputParam.getName().trim()); - } - }); - if(!duplicateParamNamesToReturn.isEmpty()) { - return Either.right(duplicateParamNamesToReturn); - } - return Either.left(Boolean.TRUE); + private boolean validateInputExistsInComponent(OperationInputDefinition input, List inputs) { + return inputs.stream().anyMatch(inp -> inp.getUniqueId().equals(input.getInputId())) + || (input.getInputId().contains(".") + && inputs.stream() + .anyMatch(inp -> inp.getUniqueId() + .equals(input.getInputId() + .substring(0, + input.getInputId() + .lastIndexOf('.'))))); } - private Boolean isInputParameterNameEmpty(Operation operationDataDefinition) { - return operationDataDefinition.getInputs().getListToscaDataDefinition().stream() - .anyMatch(inputParam -> inputParam.getName() == null || inputParam.getName().trim().equals(StringUtils.EMPTY)); - } private Boolean isOutputParameterNameEmpty(Operation operationDataDefinition) { - return operationDataDefinition.getOutputs().getListToscaDataDefinition().stream() - .anyMatch(outputParam -> outputParam.getName() == null || outputParam.getName().trim().equals(StringUtils.EMPTY)); + return operationDataDefinition.getOutputs().getListToscaDataDefinition().stream().anyMatch( + outputParam -> outputParam.getName() == null || outputParam.getName().trim().equals(StringUtils.EMPTY)); } - private Either validateInputPropertyExistInComponent(Operation operation, - List inputs, - ResponseFormatManager responseFormatManager) { - ListDataDefinition inputDefinitionListDataDefinition = operation.getInputs(); - if (inputDefinitionListDataDefinition == null) { - return Either.left(Boolean.TRUE); - } - List inputListToscaDataDefinition = inputDefinitionListDataDefinition.getListToscaDataDefinition(); - - for(OperationInputDefinition inputDefinition : inputListToscaDataDefinition ) { - if(!validateInputExistsInComponent(inputDefinition, inputs)) { - String missingPropertyName = inputDefinition.getInputId().contains(".") ? inputDefinition.getInputId().substring(inputDefinition.getInputId().indexOf(".") + 1) : inputDefinition.getInputId(); - LOGGER.error("Interface operation input property {} not found in component input properties", missingPropertyName); - ResponseFormat inputResponse = responseFormatManager.getResponseFormat(ActionStatus.INTERFACE_OPERATION_INPUT_PROPERTY_NOT_FOUND_IN_COMPONENT, missingPropertyName); - return Either.right(inputResponse); + private Either> isOutputParametersUnique(Operation operationDataDefinition) { + Set outputParamNamesSet = new HashSet<>(); + Set duplicateParamNamesToReturn = new HashSet<>(); + operationDataDefinition.getOutputs().getListToscaDataDefinition().forEach(outputParam -> { + if (!outputParamNamesSet.add(outputParam.getName().trim())) { + duplicateParamNamesToReturn.add(outputParam.getName().trim()); } + }); + if (!duplicateParamNamesToReturn.isEmpty()) { + return Either.right(duplicateParamNamesToReturn); } return Either.left(Boolean.TRUE); } - private boolean validateInputExistsInComponent(OperationInputDefinition input, - List inputs) { - return inputs.stream().anyMatch(inp -> inp.getUniqueId().equals(input.getInputId())) - || ((input.getInputId().contains(".") - && inputs.stream().anyMatch(inp -> inp.getUniqueId().equals( - input.getInputId().substring(0, input.getInputId().lastIndexOf(".")))))) ; - } - - private ResponseFormatManager getResponseFormatManager() { - return ResponseFormatManager.getInstance(); + private boolean isValidOperationType(String operationType) { + return Pattern.matches(TYPE_VALIDATION_REGEX, operationType); } } diff --git a/catalog-be/src/main/java/org/openecomp/sdc/be/datamodel/utils/InterfaceUIDataConverter.java b/catalog-be/src/main/java/org/openecomp/sdc/be/datamodel/utils/InterfaceUIDataConverter.java deleted file mode 100644 index 7fbc56a624..0000000000 --- a/catalog-be/src/main/java/org/openecomp/sdc/be/datamodel/utils/InterfaceUIDataConverter.java +++ /dev/null @@ -1,106 +0,0 @@ -/* - * 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.datamodel.utils; - -import org.openecomp.sdc.be.datatypes.elements.InterfaceOperationDataDefinition; -import org.openecomp.sdc.be.datatypes.elements.InterfaceOperationParamDataDefinition; -import org.openecomp.sdc.be.datatypes.elements.ListDataDefinition; -import org.openecomp.sdc.be.datatypes.elements.OperationInputDefinition; -import org.openecomp.sdc.be.datatypes.elements.OperationOutputDefinition; -import org.openecomp.sdc.be.model.Operation; - -import java.util.List; -import java.util.stream.Collectors; - -public class InterfaceUIDataConverter { - - private InterfaceUIDataConverter () { - - } - public static Operation convertInterfaceDataToOperationData(InterfaceOperationDataDefinition interfaceOperation){ - - ListDataDefinition inputParams = interfaceOperation.getInputParams(); - ListDataDefinition inputs = new ListDataDefinition<>(); - if (inputParams != null) { - List inputList = inputParams.getListToscaDataDefinition().stream() - .map(interfaceOperationParamDataDefinition -> new OperationInputDefinition( - interfaceOperationParamDataDefinition.getName(), - interfaceOperationParamDataDefinition.getProperty(), - interfaceOperationParamDataDefinition.getMandatory() == null ? false : interfaceOperationParamDataDefinition.getMandatory(), - interfaceOperationParamDataDefinition.getType() - )).collect(Collectors.toList()); - inputList.forEach(inputs::add); - } - ListDataDefinition outputParams = interfaceOperation.getOutputParams(); - ListDataDefinition outputs = new ListDataDefinition<>(); - if(outputParams != null) { - List outputList = outputParams.getListToscaDataDefinition().stream() - .map(interfaceOperationParamDataDefinition -> new OperationOutputDefinition( - interfaceOperationParamDataDefinition.getName(), - interfaceOperationParamDataDefinition.getMandatory() == null ? false : interfaceOperationParamDataDefinition.getMandatory(), - interfaceOperationParamDataDefinition.getType() - )).collect(Collectors.toList()); - outputList.forEach(outputs::add); - } - - Operation operationData = new Operation(); - operationData.setDescription(interfaceOperation.getDescription()); - operationData.setName(interfaceOperation.getOperationType()); - operationData.setUniqueId(interfaceOperation.getUniqueId()); - operationData.setInputs(inputs); - operationData.setOutputs(outputs); - operationData.setWorkflowId(interfaceOperation.getWorkflowId()); - operationData.setWorkflowVersionId(interfaceOperation.getWorkflowVersionId()); - operationData.setWorkflowAssociationType(interfaceOperation.getWorkflowAssociationType()); - - return operationData; - } - - public static InterfaceOperationDataDefinition convertOperationDataToInterfaceData(Operation operationData){ - ListDataDefinition inputs = operationData.getInputs(); - List inputParamList = inputs.getListToscaDataDefinition().stream() - .map(operationInputDefinition -> new InterfaceOperationParamDataDefinition(operationInputDefinition.getName(), - operationInputDefinition.getInputId(), - operationInputDefinition.isRequired(), - operationInputDefinition.getType())).collect( - Collectors.toList()); - ListDataDefinition inputParams = new ListDataDefinition<>(); - inputParamList.forEach(inputParams::add); - - ListDataDefinition outputs = operationData.getOutputs(); - List outputParamList = outputs.getListToscaDataDefinition() - .stream().map(operationOutputDefinition -> new InterfaceOperationParamDataDefinition(operationOutputDefinition.getName(), - operationOutputDefinition.isRequired(), - operationOutputDefinition.getType())).collect(Collectors.toList()); - ListDataDefinition outputParams = new ListDataDefinition<>(); - outputParamList.forEach(outputParams::add); - - InterfaceOperationDataDefinition interfaceOperationDataDefinition = new InterfaceOperationDataDefinition(); - interfaceOperationDataDefinition.setUniqueId(operationData.getUniqueId()); - interfaceOperationDataDefinition.setOperationType(operationData.getName()); - interfaceOperationDataDefinition.setDescription(operationData.getDescription()); - interfaceOperationDataDefinition.setInputParams(inputParams); - interfaceOperationDataDefinition.setOutputParams(outputParams); - interfaceOperationDataDefinition.setArtifactUUID(operationData.getImplementation().getArtifactUUID()); - interfaceOperationDataDefinition.setWorkflowId(operationData.getWorkflowId()); - interfaceOperationDataDefinition.setWorkflowVersionId(operationData.getWorkflowVersionId()); - interfaceOperationDataDefinition.setWorkflowAssociationType(operationData.getWorkflowAssociationType()); - - return interfaceOperationDataDefinition; - } - -} diff --git a/catalog-be/src/main/java/org/openecomp/sdc/be/externalapi/servlet/ArtifactExternalServlet.java b/catalog-be/src/main/java/org/openecomp/sdc/be/externalapi/servlet/ArtifactExternalServlet.java index 03c5e0fbf1..bc2ebbfb14 100644 --- a/catalog-be/src/main/java/org/openecomp/sdc/be/externalapi/servlet/ArtifactExternalServlet.java +++ b/catalog-be/src/main/java/org/openecomp/sdc/be/externalapi/servlet/ArtifactExternalServlet.java @@ -25,7 +25,6 @@ import com.jcabi.aspects.Loggable; import java.io.ByteArrayInputStream; import java.io.IOException; import java.io.InputStream; -import java.util.EnumMap; import java.util.HashMap; import java.util.Map; @@ -70,12 +69,7 @@ import javax.ws.rs.core.Context; import javax.ws.rs.core.HttpHeaders; import javax.ws.rs.core.MediaType; import javax.ws.rs.core.Response; -import java.io.ByteArrayInputStream; -import java.io.IOException; -import java.io.InputStream; -import java.util.EnumMap; -import java.util.HashMap; -import java.util.Map; + /** * This Servlet serves external users operations on artifacts. * @@ -98,7 +92,7 @@ public class ArtifactExternalServlet extends AbstractValidationsServlet { private static String startLog = "Start handle request of "; @POST - @Path("/{assetType}/{uuid}/interfaces/{operationUUID}/artifacts/{artifactUUID}") + @Path("/{assetType}/{uuid}/interfaces/{interfaceUUID}/operations/{operationUUID}/artifacts/{artifactUUID}") @Produces(MediaType.APPLICATION_JSON) @ApiOperation(value = "uploads of artifact to VF operation workflow", httpMethod = "POST", notes = "uploads of artifact to VF operation workflow") @ApiResponses(value = { @@ -127,6 +121,7 @@ public class ArtifactExternalServlet extends AbstractValidationsServlet { @ApiParam(value = "The username and password", required = true) @HeaderParam(value = Constants.AUTHORIZATION_HEADER) String authorization, @ApiParam(value = "Asset type") @PathParam("assetType") String assetType, @ApiParam(value = "The uuid of the asset as published in the metadata", required = true)@PathParam("uuid") final String uuid, + @ApiParam(value = "The uuid of the interface", required = true)@PathParam("interfaceUUID") final String interfaceUUID, @ApiParam(value = "The uuid of the operation", required = true)@PathParam("operationUUID") final String operationUUID, @ApiParam(value = "The uuid of the artifact", required = true)@PathParam("artifactUUID") final String artifactUUID, @ApiParam( hidden = true) String data) { @@ -154,7 +149,7 @@ public class ArtifactExternalServlet extends AbstractValidationsServlet { ArtifactsBusinessLogic artifactsLogic = getArtifactBL(context); Either uploadArtifactEither = artifactsLogic .updateArtifactOnInterfaceOperationByResourceUUID(data, request, ComponentTypeEnum - .findByParamName(assetType), uuid, artifactUUID, operationUUID, + .findByParamName(assetType), uuid, interfaceUUID, operationUUID, artifactUUID, resourceCommonInfo, artifactsLogic.new ArtifactOperationInfo(true, false, ArtifactOperationEnum.UPDATE)); if (uploadArtifactEither.isRight()) { log.debug(FAILED_TO_UPDATE_ARTIFACT); diff --git a/catalog-be/src/main/java/org/openecomp/sdc/be/servlets/InterfaceOperationServlet.java b/catalog-be/src/main/java/org/openecomp/sdc/be/servlets/InterfaceOperationServlet.java index 815f9763f9..801572d2f1 100644 --- a/catalog-be/src/main/java/org/openecomp/sdc/be/servlets/InterfaceOperationServlet.java +++ b/catalog-be/src/main/java/org/openecomp/sdc/be/servlets/InterfaceOperationServlet.java @@ -16,6 +16,7 @@ package org.openecomp.sdc.be.servlets; +import com.google.common.collect.ImmutableMap; import com.jcabi.aspects.Loggable; import fj.data.Either; import io.swagger.annotations.Api; @@ -23,8 +24,12 @@ import io.swagger.annotations.ApiOperation; import io.swagger.annotations.ApiParam; import io.swagger.annotations.ApiResponse; import io.swagger.annotations.ApiResponses; -import java.util.Optional; -import java.util.UUID; +import java.io.IOException; +import java.util.ArrayList; +import java.util.List; +import java.util.Map; +import java.util.stream.Collectors; +import java.util.stream.Stream; import javax.inject.Singleton; import javax.servlet.ServletContext; import javax.servlet.http.HttpServletRequest; @@ -43,10 +48,9 @@ import javax.ws.rs.core.Response; import org.openecomp.sdc.be.components.impl.InterfaceOperationBusinessLogic; import org.openecomp.sdc.be.config.BeEcompErrorManager; import org.openecomp.sdc.be.dao.api.ActionStatus; -import org.openecomp.sdc.be.datamodel.utils.InterfaceUIDataConverter; -import org.openecomp.sdc.be.datatypes.elements.InterfaceOperationDataDefinition; import org.openecomp.sdc.be.datatypes.enums.ComponentTypeEnum; -import org.openecomp.sdc.be.model.Operation; +import org.openecomp.sdc.be.datatypes.enums.JsonPresentationFields; +import org.openecomp.sdc.be.model.InterfaceDefinition; import org.openecomp.sdc.be.model.User; import org.openecomp.sdc.be.resources.data.auditing.AuditingActionEnum; import org.openecomp.sdc.be.ui.model.UiComponentDataTransfer; @@ -56,190 +60,270 @@ import org.slf4j.Logger; import org.slf4j.LoggerFactory; @Loggable(prepend = true, value = Loggable.DEBUG, trim = false) -@Path("/v1/catalog/{componentType}/{componentId}/interfaceOperations") +@Path("/v1/catalog") @Consumes(MediaType.APPLICATION_JSON) @Produces(MediaType.APPLICATION_JSON) -@Api(value = "Interface Operation", description = "Interface Operation Servlet") +@Api(value = "Interface Operation Servlet", description = "Interface Operation Servlet") @Singleton public class InterfaceOperationServlet extends AbstractValidationsServlet { - private static final Logger log = LoggerFactory.getLogger(InterfaceOperationServlet.class); - - @POST - @Consumes(MediaType.APPLICATION_JSON) - @Produces(MediaType.APPLICATION_JSON) - @Path("/") - @ApiOperation(value = "Create Interface Operation", httpMethod = "POST", notes = "Create Interface Operation", response = InterfaceOperationDataDefinition.class) - @ApiResponses(value = {@ApiResponse(code = 201, message = "Create Interface Operation"), - @ApiResponse(code = 403, message = "Restricted operation"), - @ApiResponse(code = 400, message = "Invalid content / Missing content"), - @ApiResponse(code = 409, message = "Interface Operation already exist")}) - public Response createInterfaceOperation( - @ApiParam(value = "Interface Operation to create", required = true) String data, - @ApiParam(value = "Component type") @PathParam("componentType") String componentType, - @ApiParam(value = "Component Id") @PathParam("componentId") String componentId, - @Context final HttpServletRequest request, - @HeaderParam(value = Constants.USER_ID_HEADER) String userId) { - return createOrUpdate(data, componentType ,componentId, request, userId, false); - } - - @PUT - @Consumes(MediaType.APPLICATION_JSON) - @Produces(MediaType.APPLICATION_JSON) - @Path("/") - @ApiOperation(value = "Update Interface Operation", httpMethod = "PUT", notes = "Update Interface Operation", response = InterfaceOperationDataDefinition.class) - @ApiResponses(value = {@ApiResponse(code = 201, message = "Update Interface Operation"), - @ApiResponse(code = 403, message = "Restricted operation"), - @ApiResponse(code = 400, message = "Invalid content / Missing content")}) - public Response updateInterfaceOperation( - @ApiParam(value = "Interface Operation to update", required = true) String data, - @ApiParam(value = "Component type") @PathParam("componentType") String componentType, - @ApiParam(value = "Component Id") @PathParam("componentId") String componentId, - @Context final HttpServletRequest request, - @HeaderParam(value = Constants.USER_ID_HEADER) String userId) { - return createOrUpdate(data, componentType,componentId, request, userId, true); - } - - @DELETE - @Consumes(MediaType.APPLICATION_JSON) - @Produces(MediaType.APPLICATION_JSON) - @Path("/{interfaceOperationId}") - @ApiOperation(value = "Delete Interface Operation", httpMethod = "DELETE", notes = "Delete Interface Operation", response = InterfaceOperationDataDefinition.class) - @ApiResponses(value = {@ApiResponse(code = 201, message = "Delete Interface Operation"), - @ApiResponse(code = 403, message = "Restricted operation"), - @ApiResponse(code = 400, message = "Invalid content / Missing content")}) - public Response deleteInterfaceOperation( - @ApiParam(value = "Interface Operation Id") @PathParam("interfaceOperationId") String interfaceOperationId, - @ApiParam(value = "Component Id") @PathParam("componentId") String componentId, - @Context final HttpServletRequest request, - @HeaderParam(value = Constants.USER_ID_HEADER) String userId) { - return delete(interfaceOperationId, componentId, request, userId); - } - - @GET - @Consumes(MediaType.APPLICATION_JSON) - @Produces(MediaType.APPLICATION_JSON) - @Path("/{interfaceOperationId}") - @ApiOperation(value = "Get Interface Operation", httpMethod = "GET", notes = "GET Interface Operation", response = InterfaceOperationDataDefinition.class) - @ApiResponses(value = {@ApiResponse(code = 201, message = "Get Interface Operation"), - @ApiResponse(code = 403, message = "Restricted operation"), - @ApiResponse(code = 400, message = "Invalid content / Missing content")}) - public Response getInterfaceOperation( - @ApiParam(value = "Interface Operation Id") @PathParam("interfaceOperationId") String interfaceOperationId, - @ApiParam(value = "Component Id") @PathParam("componentId") String componentId, - @Context final HttpServletRequest request, - @HeaderParam(value = Constants.USER_ID_HEADER) String userId) { - - return get(interfaceOperationId, componentId, request, userId); - } - - private Response get (String interfaceOperationId, String componentId, HttpServletRequest request, String userId){ - ServletContext context = request.getSession().getServletContext(); - String url = request.getMethod() + " " + request.getRequestURI(); - - User modifier = new User(); - modifier.setUserId(userId); - log.debug("Start get request of {} with modifier id {}", url, userId); - - try { - String componentIdLower = componentId.toLowerCase(); - InterfaceOperationBusinessLogic businessLogic = getInterfaceOperationBL(context); - - Either actionResponse = businessLogic.getInterfaceOperation(componentIdLower, interfaceOperationId, modifier, true); - if (actionResponse.isRight()) { - log.error("failed to get interface operation"); - return buildErrorResponse(actionResponse.right().value()); - } - - InterfaceOperationDataDefinition interfaceOperationDataDefinition = InterfaceUIDataConverter.convertOperationDataToInterfaceData(actionResponse.left().value()); - Object result = RepresentationUtils.toFilteredRepresentation(interfaceOperationDataDefinition); - return buildOkResponse(getComponentsUtils().getResponseFormat(ActionStatus.OK), result); + private static final Logger log = LoggerFactory.getLogger(InterfaceOperationServlet.class); + + @POST + @Consumes(MediaType.APPLICATION_JSON) + @Produces(MediaType.APPLICATION_JSON) + @Path("/resources/{resourceId}/interfaceOperations") + @ApiOperation(value = "Create Interface Operations on Resource", httpMethod = "POST", + notes = "Create Interface Operations on Resource", response = InterfaceDefinition.class, responseContainer = "List") + @ApiResponses(value = {@ApiResponse(code = 201, message = "Create Interface Operations on Resource"), + @ApiResponse(code = 400, message = "Invalid content / Missing content"), + @ApiResponse(code = 403, message = "Restricted operation"), + @ApiResponse(code = 404, message = "Resource not found"), + @ApiResponse(code = 409, message = "Interface Operation already exist")}) + public Response createInterfaceOperationsOnResource( + @ApiParam(value = "Interface Operations to create", required = true) String data, + @ApiParam(value = "Resource Id") @PathParam("resourceId") String resourceId, + @HeaderParam(value = Constants.USER_ID_HEADER) String userId, @Context final HttpServletRequest request) { + return createOrUpdate(data, ComponentTypeEnum.RESOURCE, resourceId, request, userId, false); + } + + private Response createOrUpdate(String data, ComponentTypeEnum componentType, String componentId, + HttpServletRequest request, String userId, boolean isUpdate) { + ServletContext context = request.getSession().getServletContext(); + String url = request.getMethod() + " " + request.getRequestURI(); + + User modifier = new User(); + modifier.setUserId(userId); + log.debug("Start create or update request of {} with modifier id {}", url, userId); + + try { + String componentIdLower = componentId.toLowerCase(); + InterfaceOperationBusinessLogic businessLogic = getInterfaceOperationBL(context); + + List mappedInterfaceData = getMappedInterfaceData(data, modifier, componentType); + Either, ResponseFormat> actionResponse; + if (isUpdate) { + actionResponse = + businessLogic.updateInterfaceOperation(componentIdLower, mappedInterfaceData, modifier, true); + } else { + actionResponse = + businessLogic.createInterfaceOperation(componentIdLower, mappedInterfaceData, modifier, true); + } + + if (actionResponse.isRight()) { + log.error("failed to create or update interface operation"); + return buildErrorResponse(actionResponse.right().value()); + } + + return buildOkResponse(getComponentsUtils().getResponseFormat(ActionStatus.OK), + getFormattedResponse(actionResponse.left().value())); + } catch (Exception e) { + BeEcompErrorManager.getInstance().logBeRestApiGeneralError("Interface Operation Creation or update"); + log.error("create or update interface Operation with an error", e); + return buildErrorResponse(getComponentsUtils().getResponseFormat(ActionStatus.GENERAL_ERROR)); + } + } + + private List getMappedInterfaceData(String inputJson, User user, + ComponentTypeEnum componentTypeEnum) { + Either uiComponentEither = + getComponentsUtils().convertJsonToObjectUsingObjectMapper(inputJson, user, + UiComponentDataTransfer.class, AuditingActionEnum.CREATE_RESOURCE, componentTypeEnum); + return new ArrayList<>(uiComponentEither.left().value().getInterfaces().values()); } - catch (Exception e) { - BeEcompErrorManager.getInstance().logBeRestApiGeneralError("Get Component interface operations"); - log.error("get component interface operations failed with exception", e); - return buildErrorResponse(getComponentsUtils().getResponseFormat(ActionStatus.GENERAL_ERROR)); + + private Object getFormattedResponse(List interfaceDefinitions) throws IOException { + Map> allInterfaces = + ImmutableMap.of(JsonPresentationFields.INTERFACES.getPresentation(), interfaceDefinitions); + return RepresentationUtils.toFilteredRepresentation(allInterfaces); } - } - private Response delete (String interfaceOperationId, String componentId, HttpServletRequest - request, String userId){ + @PUT + @Consumes(MediaType.APPLICATION_JSON) + @Produces(MediaType.APPLICATION_JSON) + @Path("/resources/{resourceId}/interfaceOperations") + @ApiOperation(value = "Update Interface Operations on Resource", httpMethod = "PUT", + notes = "Update Interface Operations on Resource", response = InterfaceDefinition.class, responseContainer = "List") + @ApiResponses(value = {@ApiResponse(code = 201, message = "Update Interface Operations on Resource"), + @ApiResponse(code = 400, message = "Invalid content / Missing content"), + @ApiResponse(code = 403, message = "Restricted operation"), + @ApiResponse(code = 404, message = "Resource not found")}) + public Response updateInterfaceOperationsOnResource( + @ApiParam(value = "Interface Operations to update", required = true) String data, + @ApiParam(value = "Resource Id") @PathParam("resourceId") String resourceId, + @HeaderParam(value = Constants.USER_ID_HEADER) String userId, @Context final HttpServletRequest request) { + return createOrUpdate(data, ComponentTypeEnum.RESOURCE, resourceId, request, userId, true); + } + + @DELETE + @Consumes(MediaType.APPLICATION_JSON) + @Produces(MediaType.APPLICATION_JSON) + @Path("/resources/{resourceId}/interfaces/{interfaceId}/operations/{operationId}") + @ApiOperation(value = "Delete Interface Operation from Resource", httpMethod = "DELETE", + notes = "Delete Interface Operation from Resource", response = InterfaceDefinition.class, responseContainer = "List") + @ApiResponses(value = {@ApiResponse(code = 201, message = "Delete Interface Operation from Resource"), + @ApiResponse(code = 400, message = "Invalid content / Missing content"), + @ApiResponse(code = 403, message = "Restricted operation"), + @ApiResponse(code = 404, message = "Resource not found")}) + public Response deleteInterfaceOperationsFromResource( + @ApiParam(value = "Resource Id") @PathParam("resourceId") String resourceId, + @ApiParam(value = "Interface Id") @PathParam("interfaceId") String interfaceId, + @ApiParam(value = "Operation Id") @PathParam("operationIds") String operationId, + @HeaderParam(value = Constants.USER_ID_HEADER) String userId, @Context final HttpServletRequest request) { + return delete(interfaceId, operationId, resourceId, request, userId); + } - ServletContext context = request.getSession().getServletContext(); - String url = request.getMethod() + " " + request.getRequestURI(); + private Response delete(String interfaceId, String operationIds, String componentId, HttpServletRequest request, + String userId) { - User modifier = new User(); - modifier.setUserId(userId); - log.debug("Start delete request of {} with modifier id {}", url, userId); + ServletContext context = request.getSession().getServletContext(); + String url = request.getMethod() + " " + request.getRequestURI(); - try { - String componentIdLower = componentId.toLowerCase(); - InterfaceOperationBusinessLogic businessLogic = getInterfaceOperationBL(context); + User modifier = new User(); + modifier.setUserId(userId); + log.debug("Start delete request of {} with modifier id {}", url, userId); - Either actionResponse = businessLogic.deleteInterfaceOperation(componentIdLower, interfaceOperationId, modifier, true); - if (actionResponse.isRight()) { - log.error("failed to delete interface operation"); - return buildErrorResponse(actionResponse.right().value()); - } + try { + String componentIdLower = componentId.toLowerCase(); + InterfaceOperationBusinessLogic businessLogic = getInterfaceOperationBL(context); - InterfaceOperationDataDefinition interfaceOperationDataDefinition = InterfaceUIDataConverter.convertOperationDataToInterfaceData(actionResponse.left().value()); - Object result = RepresentationUtils.toFilteredRepresentation(interfaceOperationDataDefinition); - return buildOkResponse(getComponentsUtils().getResponseFormat(ActionStatus.OK), result); + List operationsToDelete = + Stream.of(operationIds.split(",")).map(String::trim).collect(Collectors.toList()); + Either, ResponseFormat> actionResponse = businessLogic.deleteInterfaceOperation( + componentIdLower, interfaceId, operationsToDelete, modifier, true); + if (actionResponse.isRight()) { + log.error("failed to delete interface operation"); + return buildErrorResponse(actionResponse.right().value()); + } + + return buildOkResponse(getComponentsUtils().getResponseFormat(ActionStatus.OK), + getFormattedResponse(actionResponse.left().value())); + } catch (Exception e) { + BeEcompErrorManager.getInstance().logBeRestApiGeneralError("Delete Interface Operation"); + log.error("Delete interface operation with an error", e); + return buildErrorResponse(getComponentsUtils().getResponseFormat(ActionStatus.GENERAL_ERROR)); + } } - catch (Exception e) { - BeEcompErrorManager.getInstance().logBeRestApiGeneralError("Delete Interface Operation"); - log.error("Delete interface operation with an error", e); - return buildErrorResponse(getComponentsUtils().getResponseFormat(ActionStatus.GENERAL_ERROR)); + + @GET + @Consumes(MediaType.APPLICATION_JSON) + @Produces(MediaType.APPLICATION_JSON) + @Path("/resources/{resourceId}/interfaces/{interfaceId}/operations/{operationId}") + @ApiOperation(value = "Get Interface Operation from Resource", httpMethod = "GET", + notes = "GET Interface Operation from Resource", response = InterfaceDefinition.class, responseContainer = "List") + @ApiResponses(value = {@ApiResponse(code = 201, message = "Delete Interface Operation from Resource"), + @ApiResponse(code = 400, message = "Invalid content / Missing content"), + @ApiResponse(code = 403, message = "Restricted operation"), + @ApiResponse(code = 404, message = "Resource not found")}) + public Response getInterfaceOperationsFromResource( + @ApiParam(value = "Resource Id") @PathParam("resourceId") String resourceId, + @ApiParam(value = "Interface Id") @PathParam("interfaceId") String interfaceId, + @ApiParam(value = "Operation Id") @PathParam("operationId") String operationId, + @HeaderParam(value = Constants.USER_ID_HEADER) String userId, @Context final HttpServletRequest request) { + return get(interfaceId, operationId, resourceId, request, userId); } - } - - private Response createOrUpdate (String data, String componentType, String componentId, HttpServletRequest request, String userId, boolean isUpdate) { - ServletContext context = request.getSession().getServletContext(); - String url = request.getMethod() + " " + request.getRequestURI(); - - User modifier = new User(); - modifier.setUserId(userId); - log.debug("Start create or update request of {} with modifier id {}", url, userId); - - try { - String componentIdLower = componentId.toLowerCase(); - InterfaceOperationBusinessLogic businessLogic = getInterfaceOperationBL(context); - - Operation operation = getMappedOperationData(data, isUpdate, modifier, ComponentTypeEnum.findByParamName(componentType)); - Either actionResponse ; - if (isUpdate) { - actionResponse = businessLogic.updateInterfaceOperation(componentIdLower, operation, modifier, true); - } else { - actionResponse = businessLogic.createInterfaceOperation(componentIdLower, operation, modifier, true); - } - - if (actionResponse.isRight()) { - log.error("failed to update or create interface operation"); - return buildErrorResponse(actionResponse.right().value()); - } - - InterfaceOperationDataDefinition interfaceOperationDataDefinition = InterfaceUIDataConverter.convertOperationDataToInterfaceData(actionResponse.left().value()); - Object result = RepresentationUtils.toFilteredRepresentation(interfaceOperationDataDefinition); - return buildOkResponse(getComponentsUtils().getResponseFormat(ActionStatus.OK), result); + + private Response get(String interfaceId, String operationIds, String componentId, HttpServletRequest request, + String userId) { + ServletContext context = request.getSession().getServletContext(); + String url = request.getMethod() + " " + request.getRequestURI(); + + User modifier = new User(); + modifier.setUserId(userId); + log.debug("Start get request of {} with modifier id {}", url, userId); + + try { + String componentIdLower = componentId.toLowerCase(); + InterfaceOperationBusinessLogic businessLogic = getInterfaceOperationBL(context); + + List operationsToGet = + Stream.of(operationIds.split(",")).map(String::trim).collect(Collectors.toList()); + Either, ResponseFormat> actionResponse = + businessLogic.getInterfaceOperation(componentIdLower, interfaceId, operationsToGet, modifier, true); + if (actionResponse.isRight()) { + log.error("failed to get interface operation"); + return buildErrorResponse(actionResponse.right().value()); + } + + return buildOkResponse(getComponentsUtils().getResponseFormat(ActionStatus.OK), + getFormattedResponse(actionResponse.left().value())); + } catch (Exception e) { + BeEcompErrorManager.getInstance().logBeRestApiGeneralError("Get Component interface operations"); + log.error("get component interface operations failed with exception", e); + return buildErrorResponse(getComponentsUtils().getResponseFormat(ActionStatus.GENERAL_ERROR)); + } } - catch (Exception e) { - BeEcompErrorManager.getInstance().logBeRestApiGeneralError("Interface Operation Creation or update"); - log.error("create or update interface Operation with an error", e); - return buildErrorResponse(getComponentsUtils().getResponseFormat(ActionStatus.GENERAL_ERROR)); + + @POST + @Consumes(MediaType.APPLICATION_JSON) + @Produces(MediaType.APPLICATION_JSON) + @Path("/services/{serviceId}/interfaceOperations") + @ApiOperation(value = "Create Interface Operations on Service", httpMethod = "POST", + notes = "Create Interface Operations on Service", response = InterfaceDefinition.class, responseContainer = "List") + @ApiResponses(value = {@ApiResponse(code = 201, message = "Create Interface Operations on Service"), + @ApiResponse(code = 400, message = "Invalid content / Missing content"), + @ApiResponse(code = 403, message = "Restricted operation"), + @ApiResponse(code = 404, message = "Service not found"), + @ApiResponse(code = 409, message = "Interface Operation already exist")}) + public Response createInterfaceOperationsOnService( + @ApiParam(value = "Interface Operations to create", required = true) String data, + @ApiParam(value = "Service Id") @PathParam("serviceId") String serviceId, + @HeaderParam(value = Constants.USER_ID_HEADER) String userId, @Context final HttpServletRequest request) { + return createOrUpdate(data, ComponentTypeEnum.SERVICE, serviceId, request, userId, false); + } + + @PUT + @Consumes(MediaType.APPLICATION_JSON) + @Produces(MediaType.APPLICATION_JSON) + @Path("/services/{serviceId}/interfaceOperations") + @ApiOperation(value = "Update Interface Operations on Service", httpMethod = "PUT", + notes = "Update Interface Operations on Service", response = InterfaceDefinition.class, responseContainer = "List") + @ApiResponses(value = {@ApiResponse(code = 201, message = "Update Interface Operations on Service"), + @ApiResponse(code = 400, message = "Invalid content / Missing content"), + @ApiResponse(code = 403, message = "Restricted operation"), + @ApiResponse(code = 404, message = "Service not found")}) + public Response updateInterfaceOperationsOnService( + @ApiParam(value = "Interface Operations to update", required = true) String data, + @ApiParam(value = "Service Id") @PathParam("serviceId") String serviceId, + @HeaderParam(value = Constants.USER_ID_HEADER) String userId, @Context final HttpServletRequest request) { + return createOrUpdate(data, ComponentTypeEnum.SERVICE, serviceId, request, userId, true); } - } - - private Operation getMappedOperationData(String inputJson, boolean isUpdate, User user, ComponentTypeEnum componentTypeEnum){ - Either uiComponentEither = getComponentsUtils().convertJsonToObjectUsingObjectMapper(inputJson, user, UiComponentDataTransfer.class, AuditingActionEnum.CREATE_RESOURCE, componentTypeEnum); - Optional opDef = uiComponentEither.left().value().getInterfaceOperations().values().stream().findFirst(); - InterfaceOperationDataDefinition interfaceOperationDataDefinition = new InterfaceOperationDataDefinition(); - if(opDef.isPresent()) { - interfaceOperationDataDefinition = opDef.get(); - if(!isUpdate) - interfaceOperationDataDefinition.setUniqueId(UUID.randomUUID().toString()); + + @DELETE + @Consumes(MediaType.APPLICATION_JSON) + @Produces(MediaType.APPLICATION_JSON) + @Path("/services/{serviceId}/interfaces/{interfaceId}/operations/{operationId}") + @ApiOperation(value = "Delete Interface Operation from Service", httpMethod = "DELETE", + notes = "Delete Interface Operation from Service", response = InterfaceDefinition.class, responseContainer = "List") + @ApiResponses(value = {@ApiResponse(code = 201, message = "Delete Interface Operation from Service"), + @ApiResponse(code = 400, message = "Invalid content / Missing content"), + @ApiResponse(code = 403, message = "Restricted operation"), + @ApiResponse(code = 404, message = "Service not found")}) + public Response deleteInterfaceOperationsFromService( + @ApiParam(value = "Service Id") @PathParam("serviceId") String serviceId, + @ApiParam(value = "Interface Id") @PathParam("interfaceId") String interfaceId, + @ApiParam(value = "Operation Id") @PathParam("operationId") String operationId, + @HeaderParam(value = Constants.USER_ID_HEADER) String userId, @Context final HttpServletRequest request) { + return delete(interfaceId, operationId, serviceId, request, userId); + } + + @GET + @Consumes(MediaType.APPLICATION_JSON) + @Produces(MediaType.APPLICATION_JSON) + @Path("/services/{serviceId}/interfaces/{interfaceId}/operations/{operationId}") + @ApiOperation(value = "Get Interface Operation from Service", httpMethod = "GET", + notes = "GET Interface Operation from Service", response = InterfaceDefinition.class, responseContainer = "List") + @ApiResponses(value = {@ApiResponse(code = 201, message = "Get Interface Operation from Service"), + @ApiResponse(code = 400, message = "Invalid content / Missing content"), + @ApiResponse(code = 403, message = "Restricted operation"), + @ApiResponse(code = 404, message = "Service not found")}) + public Response getInterfaceOperationsFromService( + @ApiParam(value = "Service Id") @PathParam("serviceId") String serviceId, + @ApiParam(value = "Interface Id") @PathParam("interfaceId") String interfaceId, + @ApiParam(value = "Operation Id") @PathParam("operationId") String operationId, + @HeaderParam(value = Constants.USER_ID_HEADER) String userId, @Context final HttpServletRequest request) { + return get(interfaceId, operationId, serviceId, request, userId); } - return InterfaceUIDataConverter.convertInterfaceDataToOperationData(interfaceOperationDataDefinition); - } } diff --git a/catalog-be/src/main/java/org/openecomp/sdc/be/servlets/RepresentationUtils.java b/catalog-be/src/main/java/org/openecomp/sdc/be/servlets/RepresentationUtils.java index dbdfaa9897..0358e67075 100644 --- a/catalog-be/src/main/java/org/openecomp/sdc/be/servlets/RepresentationUtils.java +++ b/catalog-be/src/main/java/org/openecomp/sdc/be/servlets/RepresentationUtils.java @@ -20,7 +20,6 @@ package org.openecomp.sdc.be.servlets; - import com.fasterxml.jackson.annotation.JsonFilter; import com.fasterxml.jackson.annotation.JsonInclude; import com.fasterxml.jackson.databind.DeserializationFeature; @@ -32,20 +31,22 @@ import com.google.common.collect.ImmutableMap; import com.google.gson.Gson; import com.google.gson.JsonElement; import com.google.gson.JsonObject; +import java.io.IOException; +import java.util.ArrayList; +import java.util.Collection; +import java.util.HashMap; +import java.util.HashSet; +import java.util.List; +import java.util.Set; import org.openecomp.sdc.be.config.BeEcompErrorManager; -import org.openecomp.sdc.be.datatypes.elements.InterfaceOperationDataDefinition; import org.openecomp.sdc.be.datatypes.tosca.ToscaDataDefinition; import org.openecomp.sdc.be.model.ArtifactDefinition; import org.openecomp.sdc.be.model.InterfaceDefinition; -import org.openecomp.sdc.be.model.Operation; import org.openecomp.sdc.be.model.Resource; import org.openecomp.sdc.common.api.ArtifactGroupTypeEnum; import org.openecomp.sdc.common.api.Constants; import org.openecomp.sdc.common.log.wrappers.Logger; -import java.io.IOException; -import java.util.*; - public class RepresentationUtils { private static final Logger log = Logger.getLogger(RepresentationUtils.class); @@ -188,11 +189,8 @@ public class RepresentationUtils { .put(ArrayList.class,IsEmptyFilterMixIn.class) .put(HashSet.class,IsEmptyFilterMixIn.class) .put(InterfaceDefinition.class,IsEmptyFilterMixIn.class) - .put(Operation.class,IsEmptyFilterMixIn.class) .put(Resource.class,IsEmptyFilterMixIn.class) .put(ToscaDataDefinition.class,IsEmptyFilterMixIn.class) - .put(InterfaceOperationDataDefinition.class,IsEmptyFilterMixIn.class).build(); - - + .build(); } diff --git a/catalog-be/src/main/java/org/openecomp/sdc/be/tosca/ToscaExportHandler.java b/catalog-be/src/main/java/org/openecomp/sdc/be/tosca/ToscaExportHandler.java index 69c4cec42b..6d344f78e5 100644 --- a/catalog-be/src/main/java/org/openecomp/sdc/be/tosca/ToscaExportHandler.java +++ b/catalog-be/src/main/java/org/openecomp/sdc/be/tosca/ToscaExportHandler.java @@ -45,6 +45,7 @@ import org.openecomp.sdc.be.model.ComponentParametersView; import org.openecomp.sdc.be.model.DataTypeDefinition; import org.openecomp.sdc.be.model.GroupInstance; import org.openecomp.sdc.be.model.InputDefinition; +import org.openecomp.sdc.be.model.InterfaceDefinition; import org.openecomp.sdc.be.model.PropertyDefinition; import org.openecomp.sdc.be.model.RelationshipInfo; import org.openecomp.sdc.be.model.RequirementCapabilityRelDef; @@ -55,7 +56,9 @@ import org.openecomp.sdc.be.model.cache.ApplicationDataTypeCache; import org.openecomp.sdc.be.model.category.CategoryDefinition; import org.openecomp.sdc.be.model.jsontitan.operations.ToscaOperationFacade; import org.openecomp.sdc.be.model.jsontitan.utils.ModelConverter; +import org.openecomp.sdc.be.model.operations.api.IInterfaceLifecycleOperation; import org.openecomp.sdc.be.model.operations.api.StorageOperationStatus; +import org.openecomp.sdc.be.model.operations.impl.InterfaceLifecycleOperation; import org.openecomp.sdc.be.tosca.model.SubstitutionMapping; import org.openecomp.sdc.be.tosca.model.ToscaCapability; import org.openecomp.sdc.be.tosca.model.ToscaGroupTemplate; @@ -70,6 +73,7 @@ import org.openecomp.sdc.be.tosca.model.ToscaTopolgyTemplate; import org.openecomp.sdc.be.tosca.utils.ForwardingPathToscaUtil; import org.openecomp.sdc.be.tosca.utils.InputConverter; import org.openecomp.sdc.common.log.wrappers.Logger; +import org.openecomp.sdc.exception.ResponseFormat; import org.springframework.beans.factory.annotation.Autowired; import org.yaml.snakeyaml.DumperOptions; import org.yaml.snakeyaml.DumperOptions.FlowStyle; @@ -112,11 +116,12 @@ public class ToscaExportHandler { private GroupExportParser groupExportParser; private PropertyConvertor propertyConvertor; private InputConverter inputConverter; + private InterfaceLifecycleOperation interfaceLifecycleOperation; @Autowired public ToscaExportHandler(ApplicationDataTypeCache dataTypeCache, ToscaOperationFacade toscaOperationFacade, CapabilityRequirementConverter capabilityRequirementConverter, PolicyExportParser policyExportParser, - GroupExportParser groupExportParser, InputConverter inputConverter) { + GroupExportParser groupExportParser, InputConverter inputConverter, InterfaceLifecycleOperation interfaceLifecycleOperation) { this.dataTypeCache = dataTypeCache; this.toscaOperationFacade = toscaOperationFacade; this.capabilityRequirementConverter = capabilityRequirementConverter; @@ -124,6 +129,7 @@ public class ToscaExportHandler { this.groupExportParser = groupExportParser; this.propertyConvertor = PropertyConvertor.getInstance(); this.inputConverter = inputConverter; + this.interfaceLifecycleOperation = interfaceLifecycleOperation; } @@ -553,7 +559,20 @@ public class ToscaExportHandler { boolean isAssociatedResourceComponent) { log.debug("start convert node type for {}", component.getUniqueId()); ToscaNodeType toscaNodeType = createNodeType(component); - toscaNode.setInterface_types(addInterfaceTypeElement(component)); + + Either, StorageOperationStatus> lifecycleTypeEither = + interfaceLifecycleOperation.getAllInterfaceLifecycleTypes(); + if(lifecycleTypeEither.isRight()){ + log.debug("Failed to fetch all interface types :", lifecycleTypeEither.right().value()); + return Either.right(ToscaError.GENERAL_ERROR); + } + List allGlobalInterfaceTypes = lifecycleTypeEither.left().value() + .values() + .stream() + .map(interfaceDef -> interfaceDef.getType()) + .collect(Collectors.toList()); + toscaNode.setInterface_types(addInterfaceTypeElement(component, allGlobalInterfaceTypes)); + Either, TitanOperationStatus> dataTypesEither = dataTypeCache.getAll(); if (dataTypesEither.isRight()) { log.debug("Failed to fetch all data types :", dataTypesEither.right().value()); diff --git a/catalog-be/src/main/java/org/openecomp/sdc/be/tosca/utils/InterfacesOperationsToscaUtil.java b/catalog-be/src/main/java/org/openecomp/sdc/be/tosca/utils/InterfacesOperationsToscaUtil.java index 7afad74f64..fbef11d2e8 100644 --- a/catalog-be/src/main/java/org/openecomp/sdc/be/tosca/utils/InterfacesOperationsToscaUtil.java +++ b/catalog-be/src/main/java/org/openecomp/sdc/be/tosca/utils/InterfacesOperationsToscaUtil.java @@ -60,7 +60,7 @@ public class InterfacesOperationsToscaUtil { * @param component to work on * @return the added element */ - public static Map addInterfaceTypeElement(Component component) { + public static Map addInterfaceTypeElement(Component component, List allInterfaceTypes) { if (component instanceof Product) { return null; } @@ -68,24 +68,28 @@ public class InterfacesOperationsToscaUtil { if (MapUtils.isEmpty(interfaces)) { return null; } + Map toscaInterfaceTypes = new HashMap<>(); for (InterfaceDefinition interfaceDefinition : interfaces.values()) { - ToscaInterfaceNodeType toscaInterfaceType = new ToscaInterfaceNodeType(); - toscaInterfaceType.setDerived_from(DERIVED_FROM_STANDARD_INTERFACE); + boolean isInterfaceTypeExistInGlobalType = + allInterfaceTypes.stream().anyMatch(type -> type.equalsIgnoreCase(interfaceDefinition.getType())); + if (!isInterfaceTypeExistInGlobalType) { + ToscaInterfaceNodeType toscaInterfaceType = new ToscaInterfaceNodeType(); + toscaInterfaceType.setDerived_from(DERIVED_FROM_STANDARD_INTERFACE); - final Map operations = interfaceDefinition.getOperations(); - Map toscaOperations = new HashMap<>(); + final Map operations = interfaceDefinition.getOperations(); + Map toscaOperations = new HashMap<>(); - for (Map.Entry operationEntry : operations.entrySet()) { - toscaOperations.put(operationEntry.getValue().getName(), - null); //currently not initializing any of the operations' fields as it is not needed - } - toscaInterfaceType.setOperations(toscaOperations); - Map interfacesAsMap = getObjectAsMap(toscaInterfaceType); - Map operationsMap = (Map) interfacesAsMap.remove(OPERATIONS_KEY); - interfacesAsMap.putAll(operationsMap); + for (Map.Entry operationEntry : operations.entrySet()) { + toscaOperations.put(operationEntry.getValue().getName(), null); + } + toscaInterfaceType.setOperations(toscaOperations); + Map interfacesAsMap = getObjectAsMap(toscaInterfaceType); + Map operationsMap = (Map) interfacesAsMap.remove(OPERATIONS_KEY); + interfacesAsMap.putAll(operationsMap); - toscaInterfaceTypes.put(interfaceDefinition.getToscaResourceName(), interfacesAsMap); + toscaInterfaceTypes.put(interfaceDefinition.getType(), interfacesAsMap); + } } return MapUtils.isNotEmpty(toscaInterfaceTypes) ? toscaInterfaceTypes : null; } @@ -108,8 +112,8 @@ public class InterfacesOperationsToscaUtil { Map toscaInterfaceDefinitions = new HashMap<>(); for (InterfaceDefinition interfaceDefinition : interfaces.values()) { ToscaInterfaceDefinition toscaInterfaceDefinition = new ToscaInterfaceDefinition(); - final String toscaResourceName = interfaceDefinition.getToscaResourceName(); - toscaInterfaceDefinition.setType(toscaResourceName); + final String interfaceType = interfaceDefinition.getType(); + toscaInterfaceDefinition.setType(interfaceType); final Map operations = interfaceDefinition.getOperations(); Map toscaOperations = new HashMap<>(); @@ -133,7 +137,7 @@ public class InterfacesOperationsToscaUtil { Map operationsMap = (Map) interfaceDefAsMap.remove(OPERATIONS_KEY); handleDefaults(operationsMap); interfaceDefAsMap.putAll(operationsMap); - toscaInterfaceDefinitions.put(getLastPartOfName(toscaResourceName), interfaceDefAsMap); + toscaInterfaceDefinitions.put(getLastPartOfName(interfaceType), interfaceDefAsMap); } if (MapUtils.isNotEmpty(toscaInterfaceDefinitions)) { nodeType.setInterfaces(toscaInterfaceDefinitions); @@ -141,8 +145,8 @@ public class InterfacesOperationsToscaUtil { } /*** - * workaround for : currently "defaultp" is not being converted to "default" by the relevant code in ToscaExportHandler - * so, any string Map key named "defaultp" will have its named changed to "default" + * workaround for : currently "defaultp" is not being converted to "default" by the relevant code in + * ToscaExportHandler so, any string Map key named "defaultp" will have its named changed to "default" * @param operationsMap the map to update */ private static void handleDefaults(Map operationsMap) { -- cgit 1.2.3-korg