From eb4b9fb0f4d3b62f3b9e2da81ebe581e7d0fc6eb Mon Sep 17 00:00:00 2001 From: mojahidi Date: Tue, 10 Apr 2018 12:32:47 +0530 Subject: Fixed Review Comments - operation Business logic Added interface operation Business logic and amended validation logic Change-Id: Ia98c625d732a31b03dec2d24504ecabb367e0582 Issue-ID: SDC-1060 Signed-off-by: mojahidi --- .../impl/InterfaceOperationBusinessLogic.java | 416 +++++++++++++++++++++ .../be/components/impl/ResourceBusinessLogic.java | 97 ++++- .../validation/InterfaceOperationValidation.java | 116 +++--- .../sdc/be/servlets/BeGenericServlet.java | 4 + .../sdc/be/servlets/RepresentationUtils.java | 4 +- .../ResourceInterfaceOperationServlet.java | 317 ++++++++++++++++ .../main/resources/config/error-configuration.yaml | 2 +- .../be/components/InterfaceOperationTestUtils.java | 39 ++ .../impl/InterfaceOperationBusinessLogicTest.java | 394 +++++++++++++++++++ .../components/impl/ResourceBusinessLogicTest.java | 37 +- .../InterfaceOperationValidationTest.java | 16 - 11 files changed, 1357 insertions(+), 85 deletions(-) create mode 100644 catalog-be/src/main/java/org/openecomp/sdc/be/components/impl/InterfaceOperationBusinessLogic.java create mode 100644 catalog-be/src/main/java/org/openecomp/sdc/be/servlets/ResourceInterfaceOperationServlet.java create mode 100644 catalog-be/src/test/java/org/openecomp/sdc/be/components/impl/InterfaceOperationBusinessLogicTest.java (limited to 'catalog-be/src') 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 new file mode 100644 index 0000000000..05e7fe0941 --- /dev/null +++ b/catalog-be/src/main/java/org/openecomp/sdc/be/components/impl/InterfaceOperationBusinessLogic.java @@ -0,0 +1,416 @@ +/* + * Copyright © 2016-2018 European Support Limited + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + + +package org.openecomp.sdc.be.components.impl; + +import com.google.common.collect.Sets; +import fj.data.Either; +import org.apache.commons.collections.MapUtils; +import org.openecomp.sdc.be.components.validation.InterfaceOperationValidation; +import org.openecomp.sdc.be.dao.api.ActionStatus; +import org.openecomp.sdc.be.datamodel.utils.UiComponentDataConverter; +import org.openecomp.sdc.be.datatypes.enums.ComponentTypeEnum; +import org.openecomp.sdc.be.datatypes.enums.NodeTypeEnum; +import org.openecomp.sdc.be.model.ArtifactDefinition; +import org.openecomp.sdc.be.model.ComponentInstance; +import org.openecomp.sdc.be.model.ComponentParametersView; +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.be.model.User; +import org.openecomp.sdc.be.model.jsontitan.operations.InterfaceOperation; +import org.openecomp.sdc.be.model.jsontitan.utils.InterfaceUtils; +import org.openecomp.sdc.be.model.operations.api.StorageOperationStatus; +import org.openecomp.sdc.be.ui.model.UiComponentDataTransfer; +import org.openecomp.sdc.be.user.Role; +import org.openecomp.sdc.common.api.ArtifactGroupTypeEnum; +import org.openecomp.sdc.common.api.ArtifactTypeEnum; +import org.openecomp.sdc.exception.ResponseFormat; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Component; + +import java.util.ArrayList; +import java.util.Collection; +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import java.util.Optional; +import java.util.Set; +import java.util.UUID; +import java.util.stream.Collectors; +import java.util.stream.Stream; + +@Component("interfaceOperationBusinessLogic") +public class InterfaceOperationBusinessLogic extends ComponentBusinessLogic{ + private static final Logger LOGGER = LoggerFactory.getLogger(ResourceBusinessLogic.class); + @Autowired + private InterfaceOperationValidation interfaceOperationValidation; + + @Autowired + private ComponentInstanceBusinessLogic componentInstanceBusinessLogic; + + @Autowired + private InterfaceOperation interfaceOperation; + + public void setInterfaceOperation(InterfaceOperation interfaceOperation) { + this.interfaceOperation = interfaceOperation; + } + + public InterfaceOperationValidation getInterfaceOperationValidation() { + return interfaceOperationValidation; + } + + public void setInterfaceOperationValidation( + InterfaceOperationValidation interfaceOperationValidation) { + this.interfaceOperationValidation = interfaceOperationValidation; + } + + + public Either deleteInterfaceOperation(String resourceId, Set interfaceOperationToDelete, User user, boolean lock) { + Resource resourceToDelete = initResourceToDeleteWFOp(resourceId, interfaceOperationToDelete); + Either eitherDelete = validateUserAndRole(resourceToDelete, user, "deleteInterfaceOperation"); + if (eitherDelete != null) + return eitherDelete; + + Either storageStatus = toscaOperationFacade.getToscaElement(resourceId); + if (storageStatus.isRight()) { + return Either.right(componentsUtils.getResponseFormat(componentsUtils.convertFromStorageResponse(storageStatus.right().value(), ComponentTypeEnum.RESOURCE),"")); + } + Resource resource = storageStatus.left().value(); + if (lock) { + Either lockResult = lockComponent(resource.getUniqueId(), resource, "Delete interface Operation on a resource"); + if (lockResult.isRight()) { + LOGGER.debug("Failed to lock resource {}. Response is {}. ", resource.getName(), lockResult.right().value().getFormattedMessage()); + titanDao.rollback(); + return Either.right(lockResult.right().value()); + } + } + + try { + Optional optionalInterface = InterfaceUtils + .getInterfaceDefinitionFromToscaName(resource.getInterfaces().values(), resource.getName()); + Either sValue = getInterfaceDefinition(resource, optionalInterface.orElse(null)); + if (sValue.isRight()) { + return Either.right(sValue.right().value()); + } + InterfaceDefinition interfaceDefinition = sValue.left().value(); + Either deleteEither; + + for(String operationToDelete : interfaceOperationToDelete) { + deleteEither = deleteOperationFromInterface(interfaceDefinition, operationToDelete); + if (deleteEither.isRight()){ + return Either.right(deleteEither.right().value()); + } + interfaceDefinition = deleteEither.left().value(); + } + + Either interfaceUpdate = interfaceOperation.updateInterface(resource.getUniqueId(), interfaceDefinition); + if (interfaceUpdate.isRight()) { + LOGGER.debug("Failed to delete interface operation from resource {}. Response is {}. ", resource.getName(), interfaceUpdate.right().value()); + titanDao.rollback(); + return Either.right(componentsUtils.getResponseFormat(componentsUtils.convertFromStorageResponse(interfaceUpdate.right().value(), ComponentTypeEnum.RESOURCE))); + } + + InterfaceDefinition interfaceDef = interfaceUpdate.left().value(); + if(interfaceDef.getOperationsMap().isEmpty()){ + Either, StorageOperationStatus> deleteInterface = interfaceOperation.deleteInterface(resource, Sets.newHashSet(interfaceDef.getUniqueId())); + if (deleteInterface.isRight()) { + LOGGER.debug("Failed to delete interface from resource {}. Response is {}. ", resource.getName(), deleteInterface.right().value()); + titanDao.rollback(); + return Either.right(componentsUtils.getResponseFormat(componentsUtils.convertFromStorageResponse(deleteInterface.right().value(), ComponentTypeEnum.RESOURCE))); + } + } + + titanDao.commit(); + + } catch (Exception e){ + LOGGER.error("Exception occurred during delete interface operation : {}", e.getMessage(), e); + titanDao.rollback(); + return Either.right(componentsUtils.getResponseFormat(ActionStatus.GENERAL_ERROR)); + } finally { + graphLockOperation.unlockComponent(resource.getUniqueId(), NodeTypeEnum.Resource); + } + return Either.left(resource); + } + + public Either getInterfaceDefinition(Resource resource, + InterfaceDefinition interfaceDef) { + if (interfaceDef != null){ + return Either.left(interfaceDef); + } else { + InterfaceDefinition interfaceDefinition = new InterfaceDefinition(); + interfaceDefinition.setToscaResourceName(InterfaceUtils.createInterfaceToscaResourceName(resource.getName())); + Either interfaceCreateEither = interfaceOperation + .addInterface(resource.getUniqueId(), interfaceDefinition); + if (interfaceCreateEither.isRight()){ + StorageOperationStatus sValue = interfaceCreateEither.right().value(); + return Either.right(componentsUtils.getResponseFormat(componentsUtils.convertFromStorageResponse(sValue, + ComponentTypeEnum.RESOURCE), "")); + + } + return Either.left(interfaceCreateEither.left().value()); + } + } + + private Either deleteOperationFromInterface(InterfaceDefinition interfaceDefinition, String operationId){ + Optional> operationToRemove = interfaceDefinition.getOperationsMap().entrySet().stream() + .filter(entry -> entry.getValue().getUniqueId().equals(operationId)).findAny(); + if (operationToRemove.isPresent()){ + Map.Entry stringOperationEntry = operationToRemove.get(); + Map tempMap = interfaceDefinition.getOperationsMap(); + tempMap.remove(stringOperationEntry.getKey()); + interfaceDefinition.setOperationsMap(tempMap); + return Either.left(interfaceDefinition); + } + LOGGER.debug("Failed to delete interface operation"); + return Either.right(componentsUtils.getResponseFormat(ActionStatus.INTERFACE_OPERATION_NOT_FOUND)); + } + + private Either addOperationToInterface(InterfaceDefinition interfaceDefinition, Operation interfaceOperation){ + if(interfaceOperation.getUniqueId() == null) + interfaceOperation.setUniqueId(UUID.randomUUID().toString()); + if (interfaceOperation.getImplementationArtifact() == null){ + initNewOperation(interfaceOperation); + } + Map tempMap = interfaceDefinition.getOperationsMap(); + tempMap.put(interfaceOperation.getUniqueId(), interfaceOperation); + interfaceDefinition.setOperationsMap(tempMap); + return Either.left(interfaceDefinition); + } + + private Either updateOperationInInterface(InterfaceDefinition interfaceDefinition, Operation interfaceOperation){ + Optional> operationToUpdate = interfaceDefinition.getOperationsMap().entrySet().stream() + .filter(entry -> entry.getValue().getUniqueId().equals(interfaceOperation.getUniqueId())).findAny(); + if (operationToUpdate.isPresent()){ + Operation updatedOperation = updateOperation(operationToUpdate.get().getValue(),interfaceOperation); + Map tempMap = interfaceDefinition.getOperationsMap(); + tempMap.remove(updatedOperation.getUniqueId()); + tempMap.put(updatedOperation.getUniqueId(), updatedOperation); + interfaceDefinition.setOperationsMap(tempMap); + return Either.left(interfaceDefinition); + } + LOGGER.debug("Failed to update interface operation"); + return Either.right(componentsUtils.getResponseFormat(ActionStatus.INTERFACE_OPERATION_NOT_FOUND)); + } + + private Operation updateOperation(Operation dbOperation, Operation updatedOperation) { + dbOperation.setName(updatedOperation.getName()); + dbOperation.setDescription(updatedOperation.getDescription()); + dbOperation.setInputs(updatedOperation.getInputs()); + return dbOperation; + } + + public Either updateInterfaceOperation(String resourceId, Resource resourceUpdate, User user, boolean lock) { + return createOrUpdateInterfaceOperation(resourceId, resourceUpdate, user, true, "updateInterfaceOperation", lock); + } + + public Either createInterfaceOperation(String resourceId, Resource resourceUpdate, User user, boolean lock) { + return createOrUpdateInterfaceOperation(resourceId, resourceUpdate, user, false, "createInterfaceOperation", lock); + } + + private Either createOrUpdateInterfaceOperation(String resourceId, Resource resourceUpdate, User user, boolean isUpdate, String errorContext, boolean lock) { + Either eitherCreator = validateUserAndRole(resourceUpdate, user, errorContext); + if (eitherCreator != null) + return eitherCreator; + + Either resourceEither = getResourceDetails(resourceId); + Resource storedResource = resourceEither.left().value(); + + Map interfaceOperations = InterfaceUtils + .getInterfaceOperationsFromInterfaces(resourceUpdate.getInterfaces(), storedResource); + if(MapUtils.isEmpty(interfaceOperations) ) { + LOGGER.debug("Failed to fetch interface operations from resource {}, error {}",resourceUpdate.getUniqueId(), + ActionStatus.INTERFACE_OPERATION_NOT_FOUND); + return Either.right(componentsUtils.getResponseFormat(ActionStatus.INTERFACE_OPERATION_NOT_FOUND, + resourceUpdate.getUniqueId())); + } + + Either interfaceOperationValidationResponseEither = interfaceOperationValidation + .validateInterfaceOperations( interfaceOperations.values(), resourceId, isUpdate); + + if(interfaceOperationValidationResponseEither.isRight()) { + return Either.right(interfaceOperationValidationResponseEither.right().value()); + } + + Either lockResult = null; + if (lock) { + lockResult = lockComponent(storedResource.getUniqueId(), storedResource, + "Create or Update interface Operation on Resource"); + if (lockResult.isRight()) { + LOGGER.debug("Failed to lock resource {}. Response is {}. ", storedResource.getName(), lockResult.right().value().getFormattedMessage()); + titanDao.rollback(); + return Either.right(lockResult.right().value()); + } else { + LOGGER.debug("The resource with system name {} locked. ", storedResource.getSystemName()); + } + } + + Either result; + Map resultMap = new HashMap<>(); + + try { + Optional optionalInterface = InterfaceUtils + .getInterfaceDefinitionFromToscaName(storedResource.getInterfaces().values(), storedResource.getName()); + Either sValue = getInterfaceDefinition(storedResource, optionalInterface.orElse(null)); + if (sValue.isRight()) { + return Either.right(sValue.right().value()); + } + InterfaceDefinition interfaceDefinition = sValue.left().value(); + + for (Operation interfaceOperation : interfaceOperations.values()) { + if (isUpdate) { + result = updateOperationInInterface(interfaceDefinition, interfaceOperation); + } else { + result = addOperationToInterface(interfaceDefinition, interfaceOperation); + } + if (result.isRight()) { + titanDao.rollback(); + return Either.right(componentsUtils.getResponseFormat(ActionStatus.GENERAL_ERROR)); + } else { + interfaceDefinition = result.left().value(); + resultMap.put(interfaceDefinition.getUniqueId(), interfaceDefinition); + } + } + + Either interfaceUpdate = interfaceOperation + .updateInterface(storedResource.getUniqueId(), interfaceDefinition); + if (interfaceUpdate.isRight()) { + LOGGER.debug("Failed to add or update interface operation on resource {}. Response is {}. ", storedResource.getName(), interfaceUpdate.right().value()); + titanDao.rollback(); + return Either.right(componentsUtils.getResponseFormat(componentsUtils.convertFromStorageResponse(interfaceUpdate.right().value(), ComponentTypeEnum.RESOURCE))); + } + + titanDao.commit(); + + Resource resource = createVFWithInterfaceOperationForResponse(resourceId, resultMap); + return Either.left(resource); + } + catch (Exception e) { + titanDao.rollback(); + LOGGER.error("Exception occurred during add or update interface operation property values:{}", + e.getMessage(), e); + return Either.right(componentsUtils.getResponseFormat(ActionStatus.GENERAL_ERROR)); + } + finally { + if (lockResult != null && lockResult.isLeft() && lockResult.left().value()) { + graphLockOperation.unlockComponent(storedResource.getUniqueId(), NodeTypeEnum.Resource); + } + } + } + + private void initNewOperation(Operation operation){ + ArtifactDefinition artifactDefinition = new ArtifactDefinition(); + String artifactUUID = UUID.randomUUID().toString(); + artifactDefinition.setArtifactUUID(artifactUUID); + artifactDefinition.setUniqueId(artifactUUID); + artifactDefinition.setArtifactType(ArtifactTypeEnum.PLAN.getType()); + artifactDefinition.setArtifactGroupType(ArtifactGroupTypeEnum.LIFE_CYCLE); + operation.setImplementation(artifactDefinition); + } + + private Resource initResourceToDeleteWFOp(String resourceId, Collection interfaceOperationsToDelete) { + InterfaceDefinition id = new InterfaceDefinition(); + id.setUniqueId(UUID.randomUUID().toString()); + interfaceOperationsToDelete.forEach(interfaceOpToDelete -> id.getOperationsMap().put(interfaceOpToDelete, new Operation())); + Map interfaceDefinitionMap = new HashMap<>(); + interfaceDefinitionMap.put(id.getUniqueId(), id); + + Resource resourceToDelete = new Resource(); + resourceToDelete.setUniqueId(resourceId); + resourceToDelete.setInterfaces(interfaceDefinitionMap); + + return resourceToDelete; + } + + private Either validateUserAndRole(Resource resourceUpdate, User user, String errorContext) { + Either userEither = validateUser(user, errorContext, resourceUpdate, null, false); + if (userEither.isRight()) { + return Either.right(userEither.right().value()); + } + user = userEither.left().value(); + + Either userRoleEither = validateUserRole(user, resourceUpdate, new ArrayList<>(), null, null); + if (userRoleEither.isRight()) { + return Either.right(userRoleEither.right().value()); + } + return null; + } + + + + private Resource createVFWithInterfaceOperationForResponse(String resourceId, Map interfaceDefinitionMap) { + Resource resource = new Resource(); + resource.setUniqueId(resourceId); + resource.setInterfaces(interfaceDefinitionMap); + return resource; + } + + public Either getResourceDetails(String resourceId){ + Either resourceStorageOperationStatusEither = + toscaOperationFacade.getToscaElement(resourceId); + if (resourceStorageOperationStatusEither.isRight()) { + StorageOperationStatus errorStatus = resourceStorageOperationStatusEither.right().value(); + LOGGER.error("Failed to fetch resource information by resource id {}, error {}", resourceId, errorStatus); + return Either.right(componentsUtils + .getResponseFormat(componentsUtils.convertFromStorageResponse(errorStatus))); + } + return Either.left(resourceStorageOperationStatusEither.left().value()); + } + + + @Override + public Either, ResponseFormat> deleteMarkedComponents() { + return deleteMarkedComponents(ComponentTypeEnum.RESOURCE); + } + + @Override + public ComponentInstanceBusinessLogic getComponentInstanceBL() { + return componentInstanceBusinessLogic; + } + + @Override + public Either, ResponseFormat> getComponentInstancesFilteredByPropertiesAndInputs(String componentId, + ComponentTypeEnum componentTypeEnum, String userId, String searchText) { + return null; + } + + @Override + public Either getUiComponentDataTransferByComponentId(String resourceId, + List dataParamsToReturn) { + ComponentParametersView paramsToRetuen = new ComponentParametersView(dataParamsToReturn); + Either resourceResultEither = toscaOperationFacade.getToscaElement(resourceId, + paramsToRetuen); + + if (resourceResultEither.isRight()) { + if (resourceResultEither.right().value().equals(StorageOperationStatus.NOT_FOUND)) { + LOGGER.error("Failed to found resource with id {} ", resourceId); + Either.right(componentsUtils.getResponseFormat(ActionStatus.RESOURCE_NOT_FOUND, resourceId)); + } + + LOGGER.error("failed to get resource by id {} with filters {}", resourceId, dataParamsToReturn); + return Either.right(componentsUtils.getResponseFormatByResource( + componentsUtils.convertFromStorageResponse(resourceResultEither.right().value()), "")); + } + + Resource resource = resourceResultEither.left().value(); + UiComponentDataTransfer dataTransfer = UiComponentDataConverter.getUiDataTransferFromResourceByParams(resource, + dataParamsToReturn); + return Either.left(dataTransfer); + } +} 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 0dce2a3cd9..bbdb14f1c8 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 @@ -21,6 +21,7 @@ package org.openecomp.sdc.be.components.impl; +import com.google.common.collect.Sets; import com.google.gson.Gson; import fj.data.Either; import org.apache.commons.codec.binary.Base64; @@ -39,6 +40,7 @@ import org.openecomp.sdc.be.components.lifecycle.LifecycleChangeInfoWithAction; import org.openecomp.sdc.be.components.lifecycle.LifecycleChangeInfoWithAction.LifecycleChanceActionEnum; import org.openecomp.sdc.be.components.merge.resource.MergeResourceBLFactory; import org.openecomp.sdc.be.components.merge.resource.MergeResourceBusinessLogic; +import org.openecomp.sdc.be.components.validation.InterfaceOperationValidation; import org.openecomp.sdc.be.config.BeEcompErrorManager; import org.openecomp.sdc.be.config.BeEcompErrorManager.ErrorSeverity; import org.openecomp.sdc.be.config.ConfigurationManager; @@ -92,6 +94,8 @@ import org.openecomp.sdc.be.model.User; import org.openecomp.sdc.be.model.cache.ApplicationDataTypeCache; import org.openecomp.sdc.be.model.category.CategoryDefinition; import org.openecomp.sdc.be.model.category.SubCategoryDefinition; +import org.openecomp.sdc.be.model.jsontitan.operations.InterfaceOperation; +import org.openecomp.sdc.be.model.jsontitan.utils.InterfaceUtils; import org.openecomp.sdc.be.model.jsontitan.utils.ModelConverter; import org.openecomp.sdc.be.model.operations.api.ICacheMangerOperation; import org.openecomp.sdc.be.model.operations.api.ICapabilityTypeOperation; @@ -131,8 +135,17 @@ import org.yaml.snakeyaml.Yaml; import org.yaml.snakeyaml.parser.ParserException; import javax.servlet.ServletContext; -import java.util.*; +import java.util.ArrayList; +import java.util.Collection; +import java.util.EnumMap; +import java.util.HashMap; +import java.util.HashSet; +import java.util.Iterator; +import java.util.List; +import java.util.Map; import java.util.Map.Entry; +import java.util.Optional; +import java.util.Set; import java.util.function.Function; import java.util.regex.Matcher; import java.util.regex.Pattern; @@ -203,8 +216,15 @@ public class ResourceBusinessLogic extends ComponentBusinessLogic { @Autowired private CsarArtifactsAndGroupsBusinessLogic csarArtifactsAndGroupsBusinessLogic; + @Autowired + private InterfaceOperation interfaceOperation; + private Gson gson = new Gson(); + public void setInterfaceOperation(InterfaceOperation interfaceOperation) { + this.interfaceOperation = interfaceOperation; + } + public CsarOperation getCsarOperation() { return csarOperation; } @@ -265,6 +285,10 @@ public class ResourceBusinessLogic extends ComponentBusinessLogic { this.applicationDataTypeCache = applicationDataTypeCache; } + public void setInterfaceTypeOperation(IInterfaceLifecycleOperation interfaceTypeOperation) { + this.interfaceTypeOperation = interfaceTypeOperation; + } + /** * the method returns a list of all the resources that are certified, the * returned resources are only abstract or only none abstract according to @@ -5181,6 +5205,13 @@ public class ResourceBusinessLogic extends ComponentBusinessLogic { newResource.setDerivedFrom(null); } + Either validateAndUpdateInterfacesEither = validateAndUpdateInterfaces(resourceIdToUpdate, newResource); + if (validateAndUpdateInterfacesEither.isRight()) { + log.error("failed to validate and update Interfaces !!!"); + rollbackNeeded = true; + return Either.right(validateAndUpdateInterfacesEither.right().value()); + } + Either dataModelResponse = updateResourceMetadata(resourceIdToUpdate, newResource, user, currentResource, false, true); if (dataModelResponse.isRight()) { @@ -5652,7 +5683,7 @@ public class ResourceBusinessLogic extends ComponentBusinessLogic { ResponseFormat errorResponse = componentsUtils .getResponseFormat(ActionStatus.RESOURCE_VENDOR_NAME_CANNOT_BE_CHANGED); return Either.right(errorResponse); - + } else { Either validateVendorName = validateVendorName(null, updateInfoResource, null); @@ -5660,7 +5691,7 @@ public class ResourceBusinessLogic extends ComponentBusinessLogic { ResponseFormat errorResponse = validateVendorName.right().value(); return Either.right(errorResponse); } - } + } } return Either.left(true); } @@ -6759,5 +6790,65 @@ public class ResourceBusinessLogic extends ComponentBusinessLogic { } } + private Either validateAndUpdateInterfaces(String resourceId, Resource resourceUpdate) { + Either resourceStorageOperationStatusEither = + toscaOperationFacade.getToscaElement(resourceId); + if (resourceStorageOperationStatusEither.isRight()) { + StorageOperationStatus errorStatus = resourceStorageOperationStatusEither.right().value(); + log.error("Failed to fetch resource information by resource id {}, error {}", resourceId, errorStatus); + return Either.right(componentsUtils + .getResponseFormat(componentsUtils.convertFromStorageResponse(errorStatus))); + } + + Resource storedResource = resourceStorageOperationStatusEither.left().value(); + Map storedResourceInterfaces = storedResource.getInterfaces(); + + if(!storedResource.getName().equals(resourceUpdate.getName()) ) { + Collection interfaceDefinitionListFromToscaName = InterfaceUtils + .getInterfaceDefinitionListFromToscaName(storedResource.getInterfaces().values(), + storedResource.getName()); + + for (InterfaceDefinition interfaceDefinition : storedResourceInterfaces.values()) { + Either updateInterfaceDefinitionEither = updateInterfaceDefinition(resourceUpdate, + interfaceDefinition, + interfaceDefinitionListFromToscaName); + if(updateInterfaceDefinitionEither.isRight()) { + return Either.right(updateInterfaceDefinitionEither.right().value()); + } + } + } + + return Either.left(Boolean.TRUE); + } + + private Either updateInterfaceDefinition(Resource resourceUpdate, + InterfaceDefinition interfaceDefinition, + Collection interfaceDefinitionListFromToscaName) { + interfaceDefinitionListFromToscaName.forEach(interfaceDefinitionFromList -> { + if(interfaceDefinitionFromList.getToscaResourceName().equals(interfaceDefinition + .getToscaResourceName())) { + log.info("Going to Update interface definition toscaResourceName {} to {}", + interfaceDefinitionFromList.getToscaResourceName(), + InterfaceUtils.createInterfaceToscaResourceName(resourceUpdate.getName())); + interfaceDefinition.setToscaResourceName(InterfaceUtils + .createInterfaceToscaResourceName(resourceUpdate.getName())); + } + } ); + try { + Either interfaceUpdate = interfaceOperation + .updateInterface(resourceUpdate.getUniqueId(), interfaceDefinition); + if (interfaceUpdate.isRight()) { + log.error("Failed to Update interface {}. Response is {}. ", resourceUpdate.getName(), interfaceUpdate.right().value()); + titanDao.rollback(); + return Either.right(componentsUtils + .getResponseFormat(componentsUtils.convertFromStorageResponse(interfaceUpdate.right().value(), ComponentTypeEnum.RESOURCE))); + } + } catch (Exception e) { + log.error("Exception occurred during update interface toscaResourceName : {}", e.getMessage(), e); + return Either.right(componentsUtils.getResponseFormat(ActionStatus.GENERAL_ERROR)); + } + + return Either.left( interfaceDefinition); + } } \ No newline at end of file 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 bf3385a076..3d3cca4ed2 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 @@ -20,6 +20,7 @@ import fj.data.Either; 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.model.ComponentParametersView; @@ -53,12 +54,12 @@ public class InterfaceOperationValidation { private static final Logger LOGGER = LoggerFactory.getLogger(InterfaceOperationValidation.class); public Either validateInterfaceOperations( - Collection interfaceOperations, - String resourceId, boolean isUpdate) { + Collection interfaceOperations, + String resourceId, boolean isUpdate) { for(Operation interfaceOperation : interfaceOperations) { Either interfaceOperationValidatorResponse = validateInterfaceOperation( - interfaceOperation, resourceId, isUpdate); + interfaceOperation, resourceId, isUpdate); if (interfaceOperationValidatorResponse.isRight()) { return interfaceOperationValidatorResponse; } @@ -70,105 +71,106 @@ public class InterfaceOperationValidation { String resourceId, boolean isUpdate) { ResponseFormatManager responseFormatManager = getResponseFormatManager(); - Either interfaceOperationTypeResponse = validateInterfaceOperationType(interfaceOperation, - responseFormatManager, resourceId, isUpdate); - if (interfaceOperationTypeResponse != null) { - return interfaceOperationTypeResponse; + Either interfaceOperationTypeResponse = isInterfaceOperationTypeValid(interfaceOperation, + responseFormatManager, resourceId, isUpdate); + if (interfaceOperationTypeResponse.isRight()) { + return Either.right(interfaceOperationTypeResponse.right().value()); } - Either descriptionResponseEither = validateDescription(responseFormatManager, - interfaceOperation.getDescription()); - if (descriptionResponseEither != null) { - return descriptionResponseEither; + Either descriptionResponseEither = isValidDescription(responseFormatManager, + interfaceOperation.getDescription()); + if (descriptionResponseEither.isRight()) { + return Either.right(descriptionResponseEither.right().value()); } Either inputParametersResponse = validateInputParameters(interfaceOperation, responseFormatManager); - if(inputParametersResponse != null) { - return inputParametersResponse; + if(inputParametersResponse.isRight()) { + return Either.right(inputParametersResponse.right().value()); } - return Either.left(true); + return Either.left(Boolean.TRUE); } - private Either validateInterfaceOperationType(Operation interfaceOperation, - ResponseFormatManager responseFormatManager, - String resourceId, boolean isUpdate) { + private Either isInterfaceOperationTypeValid(Operation interfaceOperation, + ResponseFormatManager responseFormatManager, + String resourceId, boolean isUpdate) { Either operationTypeEmptyEither = isOperationTypeEmpty(responseFormatManager, - interfaceOperation.getName()); // treating name as type for now - if (operationTypeEmptyEither != null) { - return operationTypeEmptyEither; + interfaceOperation.getName()); // treating name as type for now + if (operationTypeEmptyEither.isRight()) { + return Either.right(operationTypeEmptyEither.right().value()); } Either operationTypeRegexValidationResponse = - validateOperationTypeRegex(responseFormatManager, interfaceOperation.getName()); - if (operationTypeRegexValidationResponse != null) { - return operationTypeRegexValidationResponse; + isOperationTypeRegexValid(responseFormatManager, interfaceOperation.getName()); + if (operationTypeRegexValidationResponse.isRight()) { + return Either.right(operationTypeRegexValidationResponse.right().value()); } Either operationTypeUniqueResponse = validateOperationTypeUnique(interfaceOperation, - resourceId, isUpdate, responseFormatManager ); + resourceId, isUpdate, responseFormatManager ); if(operationTypeUniqueResponse.isRight()) { return Either.right(operationTypeUniqueResponse.right().value()); } if (!operationTypeUniqueResponse.left().value()) { - LOGGER.debug("Interface Operation type {} already in use ", interfaceOperation.getName()); + LOGGER.error("Interface Operation type {} already in use ", interfaceOperation.getName()); ResponseFormat errorResponse = responseFormatManager.getResponseFormat(ActionStatus - .INTERFACE_OPERATION_TYPE_ALREADY_IN_USE, interfaceOperation.getName()); + .INTERFACE_OPERATION_TYPE_ALREADY_IN_USE, interfaceOperation.getName()); return Either.right(errorResponse); } - return null; + return Either.left(Boolean.TRUE); } - private Either validateOperationTypeRegex(ResponseFormatManager responseFormatManager, - String operationType) { + private Either isOperationTypeRegexValid(ResponseFormatManager responseFormatManager, + String operationType) { if (!isValidOperationType(operationType)) { - LOGGER.debug("Interface Operation type {} is invalid, Operation type should not contain" + - "Special character, space and should not be greater than 200 characters", 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_TYPE_INVALID, operationType); + .INTERFACE_OPERATION_TYPE_INVALID, operationType); return Either.right(errorResponse); } - return null; + return Either.left(Boolean.TRUE); } private Either isOperationTypeEmpty(ResponseFormatManager responseFormatManager, String operationType) { if (StringUtils.isEmpty(operationType)) { - LOGGER.debug("Interface Operation type is mandatory, it can't be empty"); + LOGGER.error("Interface Operation type is mandatory"); ResponseFormat errorResponse = responseFormatManager.getResponseFormat(ActionStatus - .INTERFACE_OPERATION_TYPE_MANDATORY); + .INTERFACE_OPERATION_TYPE_MANDATORY); return Either.right(errorResponse); } - return null; + return Either.left(Boolean.TRUE); } - private Either validateDescription(ResponseFormatManager responseFormatManager, - String description) { - if (description.length() > DESCRIPTION_MAX_LENGTH) { - LOGGER.debug("Interface Operation description {} is invalid, maximum 200 characters allowed", description); + 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); + .INTERFACE_OPERATION_DESCRIPTION_MAX_LENGTH); return Either.right(errorResponse); } - return null; + return Either.left(Boolean.TRUE); } private boolean isValidOperationType(String operationType) { return Pattern.matches(TYPE_VALIDATION_REGEX, operationType); } - private Either validateOperationTypeUnique(Operation interfaceOperation, - String resourceId, - boolean isUpdate, - ResponseFormatManager responseFormatManager) { + private Either validateOperationTypeUnique( + Operation interfaceOperation, + String resourceId, + boolean isUpdate, + ResponseFormatManager responseFormatManager) { boolean isOperationTypeUnique = false; ComponentParametersView filter = new ComponentParametersView(true); filter.setIgnoreInterfaces(false); Either interfaceOperationOrigin = toscaOperationFacade - .getToscaElement(resourceId, filter); + .getToscaElement(resourceId, filter); if (interfaceOperationOrigin.isRight()){ - LOGGER.debug("Failed to fetch interface operation information by resource id {} ", resourceId); + LOGGER.error("Failed to fetch interface operation information by resource id {} ", resourceId); return Either.right(responseFormatManager.getResponseFormat(ActionStatus.GENERAL_ERROR)); } @@ -189,7 +191,7 @@ public class InterfaceOperationValidation { Map operationTypes = new HashMap<>(); allOperations.forEach(operationType -> operationTypes.put(operationType.getUniqueId(), - operationType.getName()) ); + operationType.getName()) ); if (isUpdate){ isOperationTypeUnique = validateOperationTypeUniqueForUpdate(interfaceOperation, operationTypes); @@ -202,25 +204,25 @@ public class InterfaceOperationValidation { } private Either validateInputParameters(Operation interfaceOperation, ResponseFormatManager responseFormatManager) { - Either> validateInputParametersUniqueResponse = validateInputParametersUnique(interfaceOperation); + Either> validateInputParametersUniqueResponse = isInputParametersUnique(interfaceOperation); if(validateInputParametersUniqueResponse.isRight()) { - LOGGER.debug("Interface operation input parameter names {} are invalid, Input parameter names should be unique", + LOGGER.error("Interface operation input parameter names {} are invalid, Input parameter names should be unique", validateInputParametersUniqueResponse.right().value().toString()); ResponseFormat inputResponse = responseFormatManager.getResponseFormat(ActionStatus .INTERFACE_OPERATION_INPUT_NAME_INVALID, validateInputParametersUniqueResponse.right().value().toString()); return Either.right(inputResponse); } - return null; + return Either.left(Boolean.TRUE); } - private Either> validateInputParametersUnique(Operation operationDataDefinition) { + private Either> isInputParametersUnique(Operation operationDataDefinition) { Set inputParamNamesSet = new HashSet<>(); Set duplicateParamNamesToReturn = new HashSet<>(); operationDataDefinition.getInputs().getListToscaDataDefinition() .forEach(inputParam -> { - if(!inputParamNamesSet.add(inputParam.getLabel())) { - duplicateParamNamesToReturn.add(inputParam.getLabel()); + if(!inputParamNamesSet.add(inputParam.getName())) { + duplicateParamNamesToReturn.add(inputParam.getName()); } }); if(!duplicateParamNamesToReturn.isEmpty()) { @@ -235,12 +237,12 @@ public class InterfaceOperationValidation { boolean isOperationTypeUnique = false; for(Map.Entry entry : operationTypes.entrySet()){ if (entry.getKey().equals(interfaceOperation.getUniqueId()) && entry.getValue(). - equals(interfaceOperation.getName())) { + equals(interfaceOperation.getName())) { isOperationTypeUnique = true; } if(entry.getKey().equals(interfaceOperation.getUniqueId()) && !operationTypes.values() - .contains(interfaceOperation.getName())){ + .contains(interfaceOperation.getName())){ isOperationTypeUnique = true; } } diff --git a/catalog-be/src/main/java/org/openecomp/sdc/be/servlets/BeGenericServlet.java b/catalog-be/src/main/java/org/openecomp/sdc/be/servlets/BeGenericServlet.java index 0e0d20ffcb..937ec871e9 100644 --- a/catalog-be/src/main/java/org/openecomp/sdc/be/servlets/BeGenericServlet.java +++ b/catalog-be/src/main/java/org/openecomp/sdc/be/servlets/BeGenericServlet.java @@ -30,6 +30,7 @@ import org.openecomp.sdc.be.components.impl.ComponentBusinessLogic; import org.openecomp.sdc.be.components.impl.ComponentInstanceBusinessLogic; import org.openecomp.sdc.be.components.impl.ElementBusinessLogic; import org.openecomp.sdc.be.components.impl.GroupBusinessLogic; +import org.openecomp.sdc.be.components.impl.InterfaceOperationBusinessLogic; import org.openecomp.sdc.be.components.impl.MonitoringBusinessLogic; import org.openecomp.sdc.be.components.impl.PolicyBusinessLogic; import org.openecomp.sdc.be.components.impl.PolicyTypeBusinessLogic; @@ -145,6 +146,9 @@ public class BeGenericServlet extends BasicServlet { protected ResourceBusinessLogic getResourceBL(ServletContext context) { return getClassFromWebAppContext(context, () -> ResourceBusinessLogic.class); } + protected InterfaceOperationBusinessLogic getInterfaceOperationBL(ServletContext context) { + return getClassFromWebAppContext(context, () -> InterfaceOperationBusinessLogic.class); + } protected ComponentsCleanBusinessLogic getComponentCleanerBL(ServletContext context) { return getClassFromWebAppContext(context, () -> ComponentsCleanBusinessLogic.class); 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 127fb98c3c..ea6b34a1ea 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 @@ -39,6 +39,7 @@ 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; @@ -196,6 +197,7 @@ public class RepresentationUtils { .put(InterfaceDefinition.class,IsEmptyFilterMixIn.class) .put(Operation.class,IsEmptyFilterMixIn.class) .put(Resource.class,IsEmptyFilterMixIn.class) - .put(ToscaDataDefinition.class,IsEmptyFilterMixIn.class).build(); + .put(ToscaDataDefinition.class,IsEmptyFilterMixIn.class) + .put(InterfaceOperationDataDefinition.class,IsEmptyFilterMixIn.class).build(); } diff --git a/catalog-be/src/main/java/org/openecomp/sdc/be/servlets/ResourceInterfaceOperationServlet.java b/catalog-be/src/main/java/org/openecomp/sdc/be/servlets/ResourceInterfaceOperationServlet.java new file mode 100644 index 0000000000..49bce3bfe6 --- /dev/null +++ b/catalog-be/src/main/java/org/openecomp/sdc/be/servlets/ResourceInterfaceOperationServlet.java @@ -0,0 +1,317 @@ +/* + * 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.servlets; + +import com.google.common.collect.Sets; +import com.jcabi.aspects.Loggable; +import fj.data.Either; +import io.swagger.annotations.Api; +import io.swagger.annotations.ApiOperation; +import io.swagger.annotations.ApiParam; +import io.swagger.annotations.ApiResponse; +import io.swagger.annotations.ApiResponses; +import org.apache.commons.collections.CollectionUtils; +import org.apache.commons.collections.MapUtils; +import org.openecomp.sdc.be.components.impl.InterfaceOperationBusinessLogic; +import org.openecomp.sdc.be.components.impl.ResourceBusinessLogic; +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.ComponentFieldsEnum; +import org.openecomp.sdc.be.datatypes.enums.ComponentTypeEnum; +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.be.model.User; +import org.openecomp.sdc.be.model.jsontitan.utils.InterfaceUtils; +import org.openecomp.sdc.be.resources.data.auditing.AuditingActionEnum; +import org.openecomp.sdc.be.ui.model.UiComponentDataTransfer; +import org.openecomp.sdc.be.ui.model.UiResourceDataTransfer; +import org.openecomp.sdc.common.api.Constants; +import org.openecomp.sdc.exception.ResponseFormat; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import javax.inject.Singleton; +import javax.servlet.ServletContext; +import javax.servlet.http.HttpServletRequest; +import javax.ws.rs.Consumes; +import javax.ws.rs.DELETE; +import javax.ws.rs.GET; +import javax.ws.rs.HeaderParam; +import javax.ws.rs.POST; +import javax.ws.rs.PUT; +import javax.ws.rs.Path; +import javax.ws.rs.PathParam; +import javax.ws.rs.Produces; +import javax.ws.rs.core.Context; +import javax.ws.rs.core.MediaType; +import javax.ws.rs.core.Response; +import java.util.Collections; +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import java.util.Optional; +import java.util.UUID; + +@Loggable(prepend = true, value = Loggable.DEBUG, trim = false) +@Path("/v1/catalog/resources/{resourceId}/interfaceOperations") +@Consumes(MediaType.APPLICATION_JSON) +@Produces(MediaType.APPLICATION_JSON) +@Api(value = "Interface Operation", description = "Interface Operation Servlet") +@Singleton +public class ResourceInterfaceOperationServlet extends AbstractValidationsServlet { + + private static final Logger log = LoggerFactory.getLogger(ResourceInterfaceOperationServlet.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 = "Resource Id") @PathParam("resourceId") String resourceId, + @Context final HttpServletRequest request, + @HeaderParam(value = Constants.USER_ID_HEADER) String userId) { + return createOrUpdate(data, resourceId, 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 = "Resource Id") @PathParam("resourceId") String resourceId, + @Context final HttpServletRequest request, + @HeaderParam(value = Constants.USER_ID_HEADER) String userId) { + return createOrUpdate(data, resourceId, 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 = "Resource Id") @PathParam("resourceId") String resourceId, + @Context final HttpServletRequest request, + @HeaderParam(value = Constants.USER_ID_HEADER) String userId) { + return delete(interfaceOperationId, resourceId, 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 = "Resource Id") @PathParam("resourceId") String resourceId, + @Context final HttpServletRequest request, + @HeaderParam(value = Constants.USER_ID_HEADER) String userId) { + + return get(interfaceOperationId, resourceId, request, userId); + } + + private Response get (String interfaceOperationId, String resourceId, 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 { + InterfaceOperationBusinessLogic businessLogic = getInterfaceOperationBL(context); + Either resourceResponse = businessLogic.getComponentDataFilteredByParams(resourceId, modifier, Collections + .singletonList(ComponentFieldsEnum.INTERFACES.getValue())); + if (resourceResponse.isRight()) { + return buildErrorResponse(resourceResponse.right().value()); + } + + UiResourceDataTransfer uiResourceDataTransfer = (UiResourceDataTransfer) resourceResponse.left().value(); + InterfaceOperationDataDefinition interfaceOperationDataDefinition = getInterfaceOperationForResponse(interfaceOperationId, uiResourceDataTransfer.getInterfaces()); + + return buildOkResponse(getComponentsUtils().getResponseFormat(ActionStatus.OK), RepresentationUtils.toFilteredRepresentation(interfaceOperationDataDefinition)); + + } catch (Exception e) { + BeEcompErrorManager.getInstance().logBeRestApiGeneralError("Get Resource interface operations"); + log.debug("get resource interface operations failed with exception", e); + return buildErrorResponse(getComponentsUtils().getResponseFormat(ActionStatus.GENERAL_ERROR)); + } + } + + private Response delete (String interfaceOperationId, String resourceId, 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 delete request of {} with modifier id {}", url, userId); + + Response response; + + try { + String resourceIdLower = resourceId.toLowerCase(); + InterfaceOperationBusinessLogic businessLogic = getInterfaceOperationBL(context); + + Either actionResponse = businessLogic.deleteInterfaceOperation(resourceIdLower, Sets.newHashSet(interfaceOperationId), modifier, true); + + if (actionResponse.isRight()) { + log.debug("failed to delete interface operation"); + response = buildErrorResponse(actionResponse.right().value()); + return response; + } + + Resource resource = actionResponse.left().value(); + InterfaceOperationDataDefinition interfaceOperationDataDefinition = getInterfaceOperationForResponse(interfaceOperationId, resource.getInterfaces()); + Object result = RepresentationUtils.toFilteredRepresentation(interfaceOperationDataDefinition); + return buildOkResponse(getComponentsUtils().getResponseFormat(ActionStatus.OK), result); + + } catch (Exception e) { + BeEcompErrorManager.getInstance().logBeRestApiGeneralError("Delete Interface Operation"); + log.debug("Delete interface operation with an error", e); + response = buildErrorResponse(getComponentsUtils().getResponseFormat(ActionStatus.GENERAL_ERROR)); + return response; + + } + } + + private Response createOrUpdate (String data, String resourceId, 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); + + Response response; + try { + String resourceIdLower = resourceId.toLowerCase(); + InterfaceOperationBusinessLogic businessLogic = getInterfaceOperationBL(context); + + Either resourceEither = businessLogic.getResourceDetails(resourceId); + Resource origResource = resourceEither.left().value(); + + Either convertResponse = parseToResource(data, origResource, isUpdate, modifier); + if (convertResponse.isRight()) { + log.debug("failed to parse resource"); + response = buildErrorResponse(convertResponse.right().value()); + return response; + } + + Resource updatedResource = convertResponse.left().value(); + Either actionResponse ; + if (isUpdate) { + actionResponse = businessLogic.updateInterfaceOperation(resourceIdLower, updatedResource, modifier, true); + } else { + actionResponse = businessLogic.createInterfaceOperation(resourceIdLower, updatedResource, modifier, true); + } + + if (actionResponse.isRight()) { + log.debug("failed to update or create interface operation"); + response = buildErrorResponse(actionResponse.right().value()); + return response; + } + + Resource resource = actionResponse.left().value(); + List operationData = InterfaceUtils.getOperationsFromInterface(updatedResource.getInterfaces()); + InterfaceOperationDataDefinition interfaceOperationDataDefinition = getInterfaceOperationForResponse(operationData.get(0).getUniqueId(), resource.getInterfaces()); + + Object result = RepresentationUtils.toFilteredRepresentation(interfaceOperationDataDefinition); + return buildOkResponse(getComponentsUtils().getResponseFormat(ActionStatus.OK), result); + + } catch (Exception e) { + BeEcompErrorManager.getInstance().logBeRestApiGeneralError("Interface Operation Creation or update"); + log.debug("create or update interface Operation with an error", e); + response = buildErrorResponse(getComponentsUtils().getResponseFormat(ActionStatus.GENERAL_ERROR)); + return response; + + } + } + + private Either parseToResource(String resourceJson, Resource origResource, boolean isUpdate, User user) { + + Resource resource = convertToResourceObject(resourceJson, user).left().value(); + + Either uiResourceEither = getComponentsUtils().convertJsonToObjectUsingObjectMapper(resourceJson, user, UiResourceDataTransfer.class, AuditingActionEnum.CREATE_RESOURCE, ComponentTypeEnum.RESOURCE); + Optional opDef = uiResourceEither.left().value().getInterfaceOperations().values().stream().findFirst(); + InterfaceOperationDataDefinition interfaceOperationDataDefinition; + if(opDef.isPresent()) { + interfaceOperationDataDefinition = opDef.get(); + + if(!isUpdate) + interfaceOperationDataDefinition.setUniqueId(UUID.randomUUID().toString()); + + Map interfaceOperations = new HashMap<>(); + interfaceOperations.put(interfaceOperationDataDefinition.getUniqueId(), InterfaceUIDataConverter.convertInterfaceDataToOperationData(interfaceOperationDataDefinition)); + InterfaceDefinition interfaceDefinition = new InterfaceDefinition(); + interfaceDefinition.setUniqueId(UUID.randomUUID().toString()); + interfaceDefinition.setToscaResourceName(InterfaceUtils.createInterfaceToscaResourceName(origResource.getName())); + interfaceDefinition.setOperationsMap(interfaceOperations); + + Map interfaceMap = new HashMap<>(); + interfaceMap.put(interfaceDefinition.getUniqueId(), interfaceDefinition); + + resource.setInterfaces(interfaceMap); + } + + return Either.left(resource); + } + + private Either convertToResourceObject(String resourceJson, User user) { + return getComponentsUtils().convertJsonToObjectUsingObjectMapper(resourceJson, user, Resource.class, AuditingActionEnum.CREATE_RESOURCE, ComponentTypeEnum.RESOURCE); + } + + private InterfaceOperationDataDefinition getInterfaceOperationForResponse(String interfaceOperationId, Map interfaces){ + InterfaceOperationDataDefinition interfaceOperationDataDefinition = new InterfaceOperationDataDefinition(); + if(!MapUtils.isEmpty(interfaces)){ + List operationData = InterfaceUtils.getOperationsFromInterface(interfaces); + if(CollectionUtils.isNotEmpty(operationData)){ + Optional matchedOp = operationData.stream().filter(a -> a.getUniqueId().equals(interfaceOperationId)).findAny(); + if(matchedOp.isPresent()) { + interfaceOperationDataDefinition = InterfaceUIDataConverter.convertOperationDataToInterfaceData(matchedOp.get()); + } + } + } + return interfaceOperationDataDefinition; + } + +} + diff --git a/catalog-be/src/main/resources/config/error-configuration.yaml b/catalog-be/src/main/resources/config/error-configuration.yaml index 56eaaea830..b0f2e2107f 100644 --- a/catalog-be/src/main/resources/config/error-configuration.yaml +++ b/catalog-be/src/main/resources/config/error-configuration.yaml @@ -2043,7 +2043,7 @@ errors: INTERFACE_OPERATION_TYPE_INVALID: { code: 400, message: "Error: Interface Operation type %1 is Invalid, Operation type should not contain - Special character, space and should not be greater than 200 characters ", + special character, space, numbers and should not be greater than 200 characters ", messageId: "SVC4696" } #---------SVC4697----------------------------- diff --git a/catalog-be/src/test/java/org/openecomp/sdc/be/components/InterfaceOperationTestUtils.java b/catalog-be/src/test/java/org/openecomp/sdc/be/components/InterfaceOperationTestUtils.java index 65dbe87a48..52b71c5743 100644 --- a/catalog-be/src/test/java/org/openecomp/sdc/be/components/InterfaceOperationTestUtils.java +++ b/catalog-be/src/test/java/org/openecomp/sdc/be/components/InterfaceOperationTestUtils.java @@ -22,6 +22,7 @@ import org.openecomp.sdc.be.model.ArtifactDefinition; import org.openecomp.sdc.be.model.InterfaceDefinition; import org.openecomp.sdc.be.model.Operation; +import java.util.HashMap; import java.util.Map; public interface InterfaceOperationTestUtils { @@ -36,6 +37,12 @@ public interface InterfaceOperationTestUtils { id.setOperationsMap(op); return id; } + default InterfaceDefinition mockInterfaceDefinitionToReturn(String resourceNamme) { + Map operationMap = createMockOperationMap(); + return createInterface("int1", "Interface 1", + "lifecycle", "org.openecomp.interfaces.node.lifecycle." + resourceNamme, operationMap); + } + default Operation createInterfaceOperation(String uniqueID, String description, ArtifactDefinition artifactDefinition, @@ -51,5 +58,37 @@ public interface InterfaceOperationTestUtils { return operation; } + + + default Map createMockOperationMap() { + Operation operation = new Operation(); + ListDataDefinition operationInputDefinitionList = new ListDataDefinition<>(); + operationInputDefinitionList.add(createMockOperationInputDefinition("label1")); + operation.setInputs(operationInputDefinitionList); + + operation.setDefinition(false); + operation.setName("CREATE"); + operation.setUniqueId("uniqueId1"); + Map operationMap = new HashMap<>(); + operationMap.put("op1", operation); + return operationMap; + } + + default OperationInputDefinition createMockOperationInputDefinition(String name) { + OperationInputDefinition operationInputDefinition = new OperationInputDefinition(); + operationInputDefinition.setName(name); + operationInputDefinition.setUniqueId("uniqueId1"); + return operationInputDefinition; + } + + default Map createMockInterfaceDefinition(String resourceName) { + Map operationMap = createMockOperationMap(); + Map interfaceDefinitionMap = new HashMap<>(); + interfaceDefinitionMap.put("int1", createInterface("int1", "Interface 1", + "lifecycle", "org.openecomp.interfaces.node.lifecycle." + resourceName, operationMap)); + + return interfaceDefinitionMap; + } + } diff --git a/catalog-be/src/test/java/org/openecomp/sdc/be/components/impl/InterfaceOperationBusinessLogicTest.java b/catalog-be/src/test/java/org/openecomp/sdc/be/components/impl/InterfaceOperationBusinessLogicTest.java new file mode 100644 index 0000000000..f51d06d53a --- /dev/null +++ b/catalog-be/src/test/java/org/openecomp/sdc/be/components/impl/InterfaceOperationBusinessLogicTest.java @@ -0,0 +1,394 @@ +/* + * Copyright © 2016-2018 European Support Limited + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.openecomp.sdc.be.components.impl; + +import fj.data.Either; +import org.junit.Assert; +import org.junit.Before; +import org.junit.Test; +import org.mockito.InjectMocks; +import org.mockito.Mockito; +import org.mockito.MockitoAnnotations; +import org.openecomp.sdc.ElementOperationMock; +import org.openecomp.sdc.be.auditing.impl.AuditingManager; +import org.openecomp.sdc.be.components.InterfaceOperationTestUtils; +import org.openecomp.sdc.be.components.impl.generic.GenericTypeBusinessLogic; +import org.openecomp.sdc.be.components.validation.InterfaceOperationValidation; +import org.openecomp.sdc.be.components.validation.UserValidations; +import org.openecomp.sdc.be.config.ConfigurationManager; +import org.openecomp.sdc.be.dao.api.ActionStatus; +import org.openecomp.sdc.be.dao.jsongraph.TitanDao; +import org.openecomp.sdc.be.dao.titan.TitanOperationStatus; +import org.openecomp.sdc.be.datatypes.enums.ComponentTypeEnum; +import org.openecomp.sdc.be.datatypes.enums.NodeTypeEnum; +import org.openecomp.sdc.be.datatypes.enums.ResourceTypeEnum; +import org.openecomp.sdc.be.impl.ComponentsUtils; +import org.openecomp.sdc.be.impl.WebAppContextWrapper; +import org.openecomp.sdc.be.model.Component; +import org.openecomp.sdc.be.model.DataTypeDefinition; +import org.openecomp.sdc.be.model.InputDefinition; +import org.openecomp.sdc.be.model.InterfaceDefinition; +import org.openecomp.sdc.be.model.LifecycleStateEnum; +import org.openecomp.sdc.be.model.Operation; +import org.openecomp.sdc.be.model.Resource; +import org.openecomp.sdc.be.model.User; +import org.openecomp.sdc.be.model.cache.ApplicationDataTypeCache; +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.operations.NodeTypeOperation; +import org.openecomp.sdc.be.model.jsontitan.operations.TopologyTemplateOperation; +import org.openecomp.sdc.be.model.jsontitan.operations.ToscaOperationFacade; +import org.openecomp.sdc.be.model.operations.api.IElementOperation; +import org.openecomp.sdc.be.model.operations.api.IPropertyOperation; +import org.openecomp.sdc.be.model.operations.api.StorageOperationStatus; +import org.openecomp.sdc.be.model.operations.impl.GraphLockOperation; +import org.openecomp.sdc.be.user.Role; +import org.openecomp.sdc.be.user.UserBusinessLogic; +import org.openecomp.sdc.common.api.ConfigurationSource; +import org.openecomp.sdc.common.api.Constants; +import org.openecomp.sdc.common.impl.ExternalConfiguration; +import org.openecomp.sdc.common.impl.FSConfigurationSource; +import org.openecomp.sdc.exception.ResponseFormat; +import org.springframework.web.context.WebApplicationContext; + +import javax.servlet.ServletContext; +import java.util.ArrayList; +import java.util.HashMap; +import java.util.HashSet; +import java.util.List; +import java.util.Map; +import java.util.Set; +import java.util.stream.Collectors; +import java.util.stream.Stream; + +import static org.mockito.ArgumentMatchers.anyCollection; +import static org.mockito.ArgumentMatchers.anyBoolean; +import static org.mockito.ArgumentMatchers.anyObject; +import static org.mockito.ArgumentMatchers.any; +import static org.mockito.Matchers.anyString; +import static org.mockito.Matchers.eq; +import static org.mockito.Mockito.when; + +public class InterfaceOperationBusinessLogicTest implements InterfaceOperationTestUtils{ + + public static final String RESOURCE_CATEGORY1 = "Network Layer 2-3"; + public static final String RESOURCE_SUBCATEGORY = "Router"; + + + private String resourceId = "resourceId1"; + private String operationId = "uniqueId1"; + Resource resourceUpdate; + + public static final String RESOURCE_NAME = "My-Resource_Name with space"; + + final ServletContext servletContext = Mockito.mock(ServletContext.class); + IElementOperation mockElementDao; + TitanDao mockTitanDao = Mockito.mock(TitanDao.class); + UserBusinessLogic mockUserAdmin = Mockito.mock(UserBusinessLogic.class); + ToscaOperationFacade toscaOperationFacade = Mockito.mock(ToscaOperationFacade.class); + NodeTypeOperation nodeTypeOperation = Mockito.mock(NodeTypeOperation.class); + NodeTemplateOperation nodeTemplateOperation = Mockito.mock(NodeTemplateOperation.class); + TopologyTemplateOperation topologyTemplateOperation = Mockito.mock(TopologyTemplateOperation.class); + final IPropertyOperation propertyOperation = Mockito.mock(IPropertyOperation.class); + final ApplicationDataTypeCache applicationDataTypeCache = Mockito.mock(ApplicationDataTypeCache.class); + WebAppContextWrapper webAppContextWrapper = Mockito.mock(WebAppContextWrapper.class); + UserValidations userValidations = Mockito.mock(UserValidations.class); + WebApplicationContext webAppContext = Mockito.mock(WebApplicationContext.class); + + InterfaceOperation interfaceOperation = Mockito.mock(InterfaceOperation.class); + InterfaceOperationValidation operationValidator = Mockito.mock(InterfaceOperationValidation.class); + + ResponseFormatManager responseManager = null; + GraphLockOperation graphLockOperation = Mockito.mock(GraphLockOperation.class); + User user = null; + Resource resourceResponse = null; + ComponentsUtils componentsUtils; + ArtifactsBusinessLogic artifactManager = new ArtifactsBusinessLogic(); + private GenericTypeBusinessLogic genericTypeBusinessLogic = Mockito.mock(GenericTypeBusinessLogic.class); + + + @InjectMocks + InterfaceOperationBusinessLogic bl = new InterfaceOperationBusinessLogic(); + + @Before + public void setup() { + MockitoAnnotations.initMocks(this); + Mockito.reset(propertyOperation); + + ExternalConfiguration.setAppName("catalog-be"); + + // init Configuration + String appConfigDir = "src/test/resources/config/catalog-be"; + ConfigurationSource configurationSource = new FSConfigurationSource(ExternalConfiguration.getChangeListener(), appConfigDir); + ConfigurationManager configurationManager = new ConfigurationManager(configurationSource); + componentsUtils = new ComponentsUtils(Mockito.mock(AuditingManager.class)); + + // Elements + mockElementDao = new ElementOperationMock(); + + // User data and management + user = new User(); + user.setUserId("jh0003"); + user.setFirstName("Jimmi"); + user.setLastName("Hendrix"); + user.setRole(Role.ADMIN.name()); + + Either eitherGetUser = Either.left(user); + when(mockUserAdmin.getUser("jh0003", false)).thenReturn(eitherGetUser); + when(userValidations.validateUserExists(eq(user.getUserId()), anyString(), eq(false))).thenReturn(Either.left(user)); + when(userValidations.validateUserNotEmpty(eq(user), anyString())).thenReturn(Either.left(user)); + // Servlet Context attributes + when(servletContext.getAttribute(Constants.CONFIGURATION_MANAGER_ATTR)).thenReturn(configurationManager); + when(servletContext.getAttribute(Constants.WEB_APPLICATION_CONTEXT_WRAPPER_ATTR)).thenReturn(webAppContextWrapper); + when(webAppContextWrapper.getWebAppContext(servletContext)).thenReturn(webAppContext); + when(webAppContext.getBean(IElementOperation.class)).thenReturn(mockElementDao); + + Either eitherFalse = Either.left(true); + when(toscaOperationFacade.validateComponentNameExists("Root", ResourceTypeEnum.VFC, ComponentTypeEnum.RESOURCE)).thenReturn(eitherFalse); + + Either eitherCountExist = Either.left(true); + when(toscaOperationFacade.validateComponentNameExists("alreadyExists", ResourceTypeEnum.VFC, ComponentTypeEnum.RESOURCE)).thenReturn(eitherCountExist); + + Either eitherCount = Either.left(false); + when(toscaOperationFacade.validateComponentNameExists(eq(RESOURCE_NAME), any(ResourceTypeEnum.class), eq(ComponentTypeEnum.RESOURCE))).thenReturn(eitherCount); + + Either validateDerivedExists = Either.left(true); + when(toscaOperationFacade.validateToscaResourceNameExists("Root")).thenReturn(validateDerivedExists); + + Either validateDerivedNotExists = Either.left(false); + when(toscaOperationFacade.validateToscaResourceNameExists("kuku")).thenReturn(validateDerivedNotExists); + when(graphLockOperation.lockComponent(Mockito.anyString(), eq(NodeTypeEnum.Resource))).thenReturn(StorageOperationStatus.OK); + when(graphLockOperation.lockComponentByName(Mockito.anyString(), eq(NodeTypeEnum.Resource))).thenReturn(StorageOperationStatus.OK); + + // createResource + resourceResponse = createResourceObject(true); + Either eitherCreate = Either.left(resourceResponse); + Either eitherValidate = Either.left(null); + when(toscaOperationFacade.createToscaComponent(any(Resource.class))).thenReturn(eitherCreate); + when(toscaOperationFacade.validateCsarUuidUniqueness(Mockito.anyString())).thenReturn(eitherValidate); + Map emptyDataTypes = new HashMap(); + when(applicationDataTypeCache.getAll()).thenReturn(Either.left(emptyDataTypes)); + + //InterfaceOperation + + when(operationValidator.validateInterfaceOperations(anyCollection(), anyString(), anyBoolean())).thenReturn(Either.left(true)); + when(interfaceOperation.addInterface(anyString(), anyObject())).thenReturn(Either.left(mockInterfaceDefinitionToReturn(RESOURCE_NAME))); + when(interfaceOperation.updateInterface(anyString(), anyObject())).thenReturn(Either.left(mockInterfaceDefinitionToReturn(RESOURCE_NAME))); + when(interfaceOperation.deleteInterface(anyObject(), anyObject())).thenReturn(Either.left(new HashSet<>())); + when(interfaceOperation.deleteInterface(any(),any())).thenReturn(Either.left(new HashSet<>())); + when(interfaceOperation.updateInterface(any(),any())).thenReturn(Either.left(mockInterfaceDefinitionToReturn(RESOURCE_NAME))); + when(mockTitanDao.commit()).thenReturn(TitanOperationStatus.OK); + + // BL object + artifactManager.setNodeTemplateOperation(nodeTemplateOperation); + bl = new InterfaceOperationBusinessLogic(); + + bl.setUserAdmin(mockUserAdmin); + bl.setComponentsUtils(componentsUtils); + bl.setGraphLockOperation(graphLockOperation); + bl.setTitanGenericDao(mockTitanDao); + bl.setGenericTypeBusinessLogic(genericTypeBusinessLogic); + toscaOperationFacade.setNodeTypeOperation(nodeTypeOperation); + toscaOperationFacade.setTopologyTemplateOperation(topologyTemplateOperation); + bl.setToscaOperationFacade(toscaOperationFacade); + bl.setUserValidations(userValidations); + bl.setInterfaceOperation(interfaceOperation); + bl.setInterfaceOperationValidation(operationValidator); + Resource resourceCsar = createResourceObjectCsar(true); + setCanWorkOnResource(resourceCsar); + Either oldResourceRes = Either.left(resourceCsar); + when(toscaOperationFacade.getToscaFullElement(resourceCsar.getUniqueId())).thenReturn(oldResourceRes); + responseManager = ResponseFormatManager.getInstance(); + + } + + @Test + public void createInterfaceOperationTest() { + validateUserRoles(Role.ADMIN, Role.DESIGNER); + when(toscaOperationFacade.getToscaElement(resourceId)).thenReturn(Either.left(createMockResourceForAddInterface())); + resourceUpdate = setUpResourceMock(); + Either interfaceOperation = bl.createInterfaceOperation(resourceId, resourceUpdate, user, true); + Assert.assertTrue(interfaceOperation.isLeft()); + } + + + @Test + public void updateInterfaceOperationTest() { + validateUserRoles(Role.ADMIN, Role.DESIGNER); + resourceUpdate = setUpResourceMock(); + when(toscaOperationFacade.getToscaElement(resourceId)).thenReturn(Either.left(createResourceForInterfaceOperation())); + Either interfaceOperation = bl.updateInterfaceOperation(resourceId, resourceUpdate, user, true); + Assert.assertTrue(interfaceOperation.isLeft()); + } + + + @Test + public void deleteInterfaceOperationTest() { + validateUserRoles(Role.ADMIN, Role.DESIGNER); + when(toscaOperationFacade.getToscaElement(resourceId)).thenReturn(Either.left(createResourceForInterfaceOperation())); + Set idsToDelete = new HashSet<>(); + idsToDelete.add(operationId); + + Either deleteResourceResponseFormatEither = bl.deleteInterfaceOperation(resourceId, idsToDelete, user, true); + Assert.assertTrue(deleteResourceResponseFormatEither.isLeft()); + } + + @Test + public void deleteInterfaceOperationTestShouldFailWrongId() { + validateUserRoles(Role.ADMIN, Role.DESIGNER); + Set idsToDelete = new HashSet<>(); + when(toscaOperationFacade.getToscaElement(resourceId)).thenReturn(Either.left(createResourceForInterfaceOperation())); + idsToDelete.add(resourceId); + Either deleteResourceResponseFormatEither = bl.deleteInterfaceOperation(resourceId, idsToDelete, user, true); + Assert.assertFalse(deleteResourceResponseFormatEither.isLeft()); + } + + @Test + public void interfaceOperationFailedScenarioTest() { + validateUserRoles(Role.ADMIN, Role.DESIGNER); + Resource resourceWithoutInterface = new Resource(); + resourceWithoutInterface.setUniqueId(resourceId); + when(toscaOperationFacade.getToscaElement(resourceId)).thenReturn(Either.left(resourceWithoutInterface)); + Either interfaceOperation = bl.updateInterfaceOperation(resourceId, resourceWithoutInterface, user, true); + Assert.assertTrue(interfaceOperation.isRight()); + } + + private void validateUserRoles(Role... roles) { + List listOfRoles = Stream.of(roles).collect(Collectors.toList()); + when(userValidations.validateUserRole(user, listOfRoles)).thenReturn(Either.left(true)); + } + private Resource createMockResourceForAddInterface () { + Resource resource = new Resource(); + resource.setUniqueId(resourceId); + resource.setName(RESOURCE_NAME); + resource.addCategory(RESOURCE_CATEGORY1, RESOURCE_SUBCATEGORY); + resource.setDescription("My short description"); + + Map operationMap = new HashMap<>(); + Map interfaceDefinitionMap = new HashMap<>(); + interfaceDefinitionMap.put("int1", createInterface("int1", "Interface 1", + "lifecycle", "org.openecomp.interfaces.node.lifecycle." + RESOURCE_NAME, operationMap)); + resource.setInterfaces(interfaceDefinitionMap); + List inputDefinitionList = new ArrayList<>(); + inputDefinitionList.add(createInputDefinition("uniqueId1")); + resource.setInputs(inputDefinitionList); + + return resource; + } + + private Resource setCanWorkOnResource(Resource resource) { + resource.setLifecycleState(LifecycleStateEnum.NOT_CERTIFIED_CHECKOUT); + resource.setLastUpdaterUserId(user.getUserId()); + return resource; + } + + private Resource setUpResourceMock(){ + Resource resource = new Resource(); + resource.setUniqueId(resourceId); + resource.setName(RESOURCE_NAME); + resource.addCategory(RESOURCE_CATEGORY1, RESOURCE_SUBCATEGORY); + resource.setDescription("My short description"); + resource.setInterfaces(createMockInterfaceDefinition(RESOURCE_NAME)); + + List inputDefinitionList = new ArrayList<>(); + inputDefinitionList.add(createInputDefinition("uniqueId1")); + resource.setInputs(inputDefinitionList); + + return resource; + } + + private InputDefinition createInputDefinition(String inputId) { + InputDefinition inputDefinition = new InputDefinition(); + inputDefinition.setInputId(inputId); + inputDefinition.setDescription("Input Description"); + + return inputDefinition; + + } + private Resource createResourceForInterfaceOperation() { + Resource resource = new Resource(); + resource.setUniqueId(resourceId); + resource.setName(RESOURCE_NAME); + resource.addCategory(RESOURCE_CATEGORY1, RESOURCE_SUBCATEGORY); + resource.setDescription("Resource name for response"); + resource.setInterfaces(createMockInterfaceDefinition(RESOURCE_NAME)); + return resource; + } + + private Resource createResourceObjectCsar(boolean afterCreate) { + Resource resource = new Resource(); + resource.setName(RESOURCE_NAME); + resource.addCategory(RESOURCE_CATEGORY1, RESOURCE_SUBCATEGORY); + resource.setDescription("My short description"); + List tgs = new ArrayList(); + tgs.add("test"); + tgs.add(resource.getName()); + resource.setTags(tgs); + List template = new ArrayList(); + template.add("Root"); + resource.setDerivedFrom(template); + resource.setVendorName("Motorola"); + resource.setVendorRelease("1.0.0"); + resource.setResourceVendorModelNumber(""); + resource.setContactId("ya5467"); + resource.setIcon("MyIcon"); + resource.setCsarUUID("valid_vf.csar"); + resource.setCsarVersion("1"); + + if (afterCreate) { + resource.setName(resource.getName()); + resource.setVersion("0.1"); + + resource.setUniqueId(resource.getName().toLowerCase() + ":" + resource.getVersion()); + resource.setCreatorUserId(user.getUserId()); + resource.setCreatorFullName(user.getFirstName() + " " + user.getLastName()); + resource.setLifecycleState(LifecycleStateEnum.NOT_CERTIFIED_CHECKOUT); + } + return resource; + } + + private Resource createResourceObject(boolean afterCreate) { + Resource resource = new Resource(); + resource.setName(RESOURCE_NAME); + resource.addCategory(RESOURCE_CATEGORY1, RESOURCE_SUBCATEGORY); + resource.setDescription("My short description"); + List tgs = new ArrayList(); + tgs.add("test"); + tgs.add(resource.getName()); + resource.setTags(tgs); + List template = new ArrayList(); + template.add("Root"); + resource.setDerivedFrom(template); + resource.setVendorName("Motorola"); + resource.setVendorRelease("1.0.0"); + resource.setContactId("ya5467"); + resource.setIcon("MyIcon"); + + if (afterCreate) { + resource.setName(resource.getName()); + resource.setVersion("0.1"); + resource.setUniqueId(resource.getName().toLowerCase() + ":" + resource.getVersion()); + resource.setCreatorUserId(user.getUserId()); + resource.setCreatorFullName(user.getFirstName() + " " + user.getLastName()); + resource.setLifecycleState(LifecycleStateEnum.NOT_CERTIFIED_CHECKOUT); + } + return resource; + } + + + +} \ No newline at end of file diff --git a/catalog-be/src/test/java/org/openecomp/sdc/be/components/impl/ResourceBusinessLogicTest.java b/catalog-be/src/test/java/org/openecomp/sdc/be/components/impl/ResourceBusinessLogicTest.java index 8054baf15f..75aa10aa64 100644 --- a/catalog-be/src/test/java/org/openecomp/sdc/be/components/impl/ResourceBusinessLogicTest.java +++ b/catalog-be/src/test/java/org/openecomp/sdc/be/components/impl/ResourceBusinessLogicTest.java @@ -29,8 +29,8 @@ import org.mockito.InjectMocks; import org.mockito.Mockito; import org.mockito.MockitoAnnotations; import org.openecomp.sdc.ElementOperationMock; -import org.openecomp.sdc.be.auditing.impl.AuditingLogFormatUtil; import org.openecomp.sdc.be.auditing.impl.AuditingManager; +import org.openecomp.sdc.be.components.InterfaceOperationTestUtils; import org.openecomp.sdc.be.components.impl.ArtifactsBusinessLogic.ArtifactOperationEnum; import org.openecomp.sdc.be.components.impl.generic.GenericTypeBusinessLogic; import org.openecomp.sdc.be.components.lifecycle.LifecycleBusinessLogic; @@ -39,6 +39,9 @@ import org.openecomp.sdc.be.components.validation.UserValidations; import org.openecomp.sdc.be.config.ConfigurationManager; import org.openecomp.sdc.be.dao.api.ActionStatus; import org.openecomp.sdc.be.dao.jsongraph.TitanDao; +import org.openecomp.sdc.be.dao.titan.TitanOperationStatus; +import org.openecomp.sdc.be.datatypes.elements.ListDataDefinition; +import org.openecomp.sdc.be.datatypes.elements.OperationInputDefinition; import org.openecomp.sdc.be.datatypes.enums.ComponentTypeEnum; import org.openecomp.sdc.be.datatypes.enums.NodeTypeEnum; import org.openecomp.sdc.be.datatypes.enums.ResourceTypeEnum; @@ -48,18 +51,22 @@ import org.openecomp.sdc.be.model.ArtifactDefinition; import org.openecomp.sdc.be.model.Component; import org.openecomp.sdc.be.model.DataTypeDefinition; import org.openecomp.sdc.be.model.InputDefinition; +import org.openecomp.sdc.be.model.InterfaceDefinition; import org.openecomp.sdc.be.model.LifeCycleTransitionEnum; import org.openecomp.sdc.be.model.LifecycleStateEnum; +import org.openecomp.sdc.be.model.Operation; import org.openecomp.sdc.be.model.PropertyDefinition; import org.openecomp.sdc.be.model.Resource; import org.openecomp.sdc.be.model.User; import org.openecomp.sdc.be.model.cache.ApplicationDataTypeCache; +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.operations.NodeTypeOperation; import org.openecomp.sdc.be.model.jsontitan.operations.TopologyTemplateOperation; import org.openecomp.sdc.be.model.jsontitan.operations.ToscaOperationFacade; import org.openecomp.sdc.be.model.operations.api.ICapabilityTypeOperation; import org.openecomp.sdc.be.model.operations.api.IElementOperation; +import org.openecomp.sdc.be.model.operations.api.IInterfaceLifecycleOperation; import org.openecomp.sdc.be.model.operations.api.IPropertyOperation; import org.openecomp.sdc.be.model.operations.api.StorageOperationStatus; import org.openecomp.sdc.be.model.operations.impl.CacheMangerOperation; @@ -98,11 +105,14 @@ import static org.junit.Assert.assertFalse; import static org.junit.Assert.assertNotNull; import static org.junit.Assert.assertTrue; import static org.mockito.ArgumentMatchers.any; +import static org.mockito.ArgumentMatchers.anyCollection; +import static org.mockito.ArgumentMatchers.anyBoolean; +import static org.mockito.ArgumentMatchers.anyObject; import static org.mockito.Matchers.anyString; import static org.mockito.Matchers.eq; import static org.mockito.Mockito.when; -public class ResourceBusinessLogicTest { +public class ResourceBusinessLogicTest implements InterfaceOperationTestUtils{ private static final Logger log = LoggerFactory.getLogger(ResourceBusinessLogicTest.class); public static final String RESOURCE_CATEGORY = "Network Layer 2-3/Router"; @@ -112,6 +122,10 @@ public class ResourceBusinessLogicTest { public static final String UPDATED_CATEGORY = "Network Layer 2-3/Gateway"; public static final String UPDATED_SUBCATEGORY = "Gateway"; + private String resourceId = "resourceId1"; + private String operationId = "uniqueId1"; + Resource resourceUpdate; + public static final String RESOURCE_NAME = "My-Resource_Name with space"; private static final String GENERIC_VF_NAME = "org.openecomp.resource.abstract.nodes.VF"; private static final String GENERIC_CR_NAME = "org.openecomp.resource.abstract.nodes.CR"; @@ -133,7 +147,9 @@ public class ResourceBusinessLogicTest { WebAppContextWrapper webAppContextWrapper = Mockito.mock(WebAppContextWrapper.class); UserValidations userValidations = Mockito.mock(UserValidations.class); WebApplicationContext webAppContext = Mockito.mock(WebApplicationContext.class); - AuditingLogFormatUtil auditingLogFormatter = Mockito.mock(AuditingLogFormatUtil.class); + IInterfaceLifecycleOperation interfaceTypeOperation = Mockito.mock(IInterfaceLifecycleOperation.class); + InterfaceOperation interfaceOperation = Mockito.mock(InterfaceOperation.class); + @InjectMocks ResourceBusinessLogic bl = new ResourceBusinessLogic(); ResponseFormatManager responseManager = null; @@ -201,7 +217,7 @@ public class ResourceBusinessLogicTest { /*when(toscaOperationFacade.validateComponentNameExists(RESOURCE_NAME, ResourceTypeEnum.VF, ComponentTypeEnum.RESOURCE)).thenReturn(eitherCount); when(toscaOperationFacade.validateComponentNameExists(RESOURCE_NAME, ResourceTypeEnum.PNF, ComponentTypeEnum.RESOURCE)).thenReturn(eitherCount); when(toscaOperationFacade.validateComponentNameExists(RESOURCE_NAME, ResourceTypeEnum.CR, ComponentTypeEnum.RESOURCE)).thenReturn(eitherCount);*/ - + when(interfaceOperation.updateInterface(anyString(), anyObject())).thenReturn(Either.left(mockInterfaceDefinitionToReturn(RESOURCE_NAME))); Either validateDerivedExists = Either.left(true); when(toscaOperationFacade.validateToscaResourceNameExists("Root")).thenReturn(validateDerivedExists); @@ -218,6 +234,7 @@ public class ResourceBusinessLogicTest { when(toscaOperationFacade.validateCsarUuidUniqueness(Mockito.anyString())).thenReturn(eitherValidate); Map emptyDataTypes = new HashMap(); when(applicationDataTypeCache.getAll()).thenReturn(Either.left(emptyDataTypes)); + when(mockTitanDao.commit()).thenReturn(TitanOperationStatus.OK); // BL object artifactManager.setNodeTemplateOperation(nodeTemplateOperation); @@ -239,6 +256,9 @@ public class ResourceBusinessLogicTest { toscaOperationFacade.setTopologyTemplateOperation(topologyTemplateOperation); bl.setToscaOperationFacade(toscaOperationFacade); bl.setUserValidations(userValidations); + bl.setInterfaceTypeOperation(interfaceTypeOperation); + bl.setInterfaceOperation(interfaceOperation); + Resource resourceCsar = createResourceObjectCsar(true); setCanWorkOnResource(resourceCsar); Either oldResourceRes = Either.left(resourceCsar); @@ -334,7 +354,8 @@ public class ResourceBusinessLogicTest { when(toscaOperationFacade.getLatestComponentByCsarOrName(ComponentTypeEnum.RESOURCE, resource.getCsarUUID(), resource.getSystemName())).thenReturn(resourceLinkedToCsarRes); Either validateDerivedExists = Either.left(true); when(toscaOperationFacade.validateToscaResourceNameExists("Root")).thenReturn(validateDerivedExists); - + Either eitherUpdate = Either.left(setCanWorkOnResource(resource)); + when(toscaOperationFacade.getToscaElement(resource.getUniqueId())).thenReturn(eitherUpdate); Either dataModelResponse = Either.left(resource); when(toscaOperationFacade.updateToscaElement(resource)).thenReturn(dataModelResponse); Either updateResponse = bl.validateAndUpdateResourceFromCsar(resource, user, null, null, resource.getUniqueId()); @@ -868,6 +889,7 @@ public class ResourceBusinessLogicTest { @Test public void testResourceNameWrongFormat_UPDATE() { Resource resource = createResourceObject(true); + resource.setInterfaces(createMockInterfaceDefinition(RESOURCE_NAME)); Resource updatedResource = createResourceObject(true); // this is in order to prevent failing with 403 earlier @@ -889,6 +911,7 @@ public class ResourceBusinessLogicTest { @Test public void testResourceNameAfterCertify_UPDATE() { Resource resource = createResourceObject(true); + resource.setInterfaces(createMockInterfaceDefinition(RESOURCE_NAME)); Resource updatedResource = createResourceObject(true); // this is in order to prevent failing with 403 earlier @@ -932,6 +955,8 @@ public class ResourceBusinessLogicTest { @Test public void testResourceNameAlreadyExist_UPDATE() { Resource resource = createResourceObject(true); + resource.setInterfaces(createMockInterfaceDefinition(RESOURCE_NAME)); + Resource updatedResource = createResourceObject(true); // this is in order to prevent failing with 403 earlier @@ -1815,6 +1840,4 @@ public class ResourceBusinessLogicTest { List listOfRoles = Stream.of(roles).collect(Collectors.toList()); when(userValidations.validateUserRole(user, listOfRoles)).thenReturn(Either.left(true)); } - - } diff --git a/catalog-be/src/test/java/org/openecomp/sdc/be/components/validation/InterfaceOperationValidationTest.java b/catalog-be/src/test/java/org/openecomp/sdc/be/components/validation/InterfaceOperationValidationTest.java index c05dbda974..792521c484 100644 --- a/catalog-be/src/test/java/org/openecomp/sdc/be/components/validation/InterfaceOperationValidationTest.java +++ b/catalog-be/src/test/java/org/openecomp/sdc/be/components/validation/InterfaceOperationValidationTest.java @@ -192,22 +192,6 @@ public class InterfaceOperationValidationTest implements InterfaceOperationTestU return interfaceDefinitionMap; } - private Map createMockOperationMap() { - Operation operation = new Operation(); - operation.setDefinition(false); - operation.setName("CREATE"); - Map operationMap = new HashMap<>(); - operationMap.put("op1", operation); - return operationMap; - } - - - private OperationInputDefinition createMockOperationInputDefinition(String label) { - OperationInputDefinition operationInputDefinition = new OperationInputDefinition(); - operationInputDefinition.setLabel(label); - return operationInputDefinition; - } - private class InterfaceOperationValidationUtilTest extends InterfaceOperationValidation { protected ResponseFormatManager getResponseFormatManager() { -- cgit 1.2.3-korg