From f6b81e6da9b95ec5ef2c8b2b7b50fb8de9f3dd28 Mon Sep 17 00:00:00 2001 From: "andre.schmid" Date: Thu, 24 Mar 2022 13:11:04 +0000 Subject: Log partial VSP deletion Adds entries to the VSP activity log identifying the VSP versions deleted from the MinIO client, and also if the deletion was fully complete. If the VSP deletion from the database fails, there will be registry of what happened with the MinIO deletion. Do some refactor in the VendorSoftwareProductsImpl in relation to the VSP deletion flow and responses. Issue-ID: SDC-3931 Change-Id: I75cb9d7fb74a48db01b242a5f70fefa0a88faa0d Signed-off-by: andre.schmid --- .../sdcrests/errors/DefaultExceptionMapper.java | 4 +- .../errorCodesToResponseStatusMapping.json | 5 + .../sdcrests/vsp/rest/CatalogVspClient.java | 3 +- .../VendorSoftwareProductsExceptionSupplier.java | 91 +++++++++++++ .../vsp/rest/services/CatalogVspClientImpl.java | 22 +-- .../rest/services/VendorSoftwareProductsImpl.java | 114 +++++++++++----- .../OrchestrationTemplateCandidateImplTest.java | 18 --- .../services/VendorSoftwareProductsImplTest.java | 149 +++++++++++++++------ 8 files changed, 294 insertions(+), 112 deletions(-) create mode 100644 openecomp-be/api/openecomp-sdc-rest-webapp/vendor-software-products-rest/vendor-software-products-rest-services/src/main/java/org/openecomp/sdcrests/vsp/rest/exception/VendorSoftwareProductsExceptionSupplier.java (limited to 'openecomp-be/api/openecomp-sdc-rest-webapp') diff --git a/openecomp-be/api/openecomp-sdc-rest-webapp/openecomp-sdc-common-rest/src/main/java/org/openecomp/sdcrests/errors/DefaultExceptionMapper.java b/openecomp-be/api/openecomp-sdc-rest-webapp/openecomp-sdc-common-rest/src/main/java/org/openecomp/sdcrests/errors/DefaultExceptionMapper.java index a256af785c..22d6d90d8a 100644 --- a/openecomp-be/api/openecomp-sdc-rest-webapp/openecomp-sdc-common-rest/src/main/java/org/openecomp/sdcrests/errors/DefaultExceptionMapper.java +++ b/openecomp-be/api/openecomp-sdc-rest-webapp/openecomp-sdc-common-rest/src/main/java/org/openecomp/sdcrests/errors/DefaultExceptionMapper.java @@ -80,8 +80,8 @@ public class DefaultExceptionMapper implements ExceptionMapper { return buildResponse(Status.INTERNAL_SERVER_ERROR, code); } - private Response buildResponse(Status notFound, ErrorCode code) { - return Response.status(notFound).entity(toEntity(notFound, code)).build(); + private Response buildResponse(final Status status, final ErrorCode code) { + return Response.status(status).entity(toEntity(status, code)).build(); } private Response transform(ConstraintViolationException validationException) { diff --git a/openecomp-be/api/openecomp-sdc-rest-webapp/openecomp-sdc-common-rest/src/main/resources/errorCodesToResponseStatusMapping.json b/openecomp-be/api/openecomp-sdc-rest-webapp/openecomp-sdc-common-rest/src/main/resources/errorCodesToResponseStatusMapping.json index 96c06ae97c..5b2e808781 100644 --- a/openecomp-be/api/openecomp-sdc-rest-webapp/openecomp-sdc-common-rest/src/main/resources/errorCodesToResponseStatusMapping.json +++ b/openecomp-be/api/openecomp-sdc-rest-webapp/openecomp-sdc-common-rest/src/main/resources/errorCodesToResponseStatusMapping.json @@ -9,6 +9,11 @@ "VSP_UPLOAD_STATUS_NOT_FOUND_ERROR": "NOT_FOUND", "VSP_UPLOAD_ALREADY_FINISHED_ERROR": "INTERNAL_SERVER_ERROR", "VSP_UPLOAD_ALREADY_IN_STATUS_ERROR": "BAD_REQUEST", + "VSP_DELETE_ALREADY_IN_USE_BY_VF": "FORBIDDEN", + "VSP_DELETE_NOT_ARCHIVED": "FORBIDDEN", + "VSP_DELETE_GENERIC_ERROR": "INTERNAL_SERVER_ERROR", + "VSP_DELETE_FROM_STORAGE_ERROR": "INTERNAL_SERVER_ERROR", + "VSP_DELETE_FROM_DATABASE_ERROR": "INTERNAL_SERVER_ERROR", "ORCHESTRATION_NOT_FOUND": "NOT_FOUND", "UPLOAD_INVALID" : "PRECONDITION_FAILED", "PACKAGE_NOT_FOUND": "NOT_FOUND", diff --git a/openecomp-be/api/openecomp-sdc-rest-webapp/vendor-software-products-rest/vendor-software-products-rest-services/src/main/java/org/openecomp/sdcrests/vsp/rest/CatalogVspClient.java b/openecomp-be/api/openecomp-sdc-rest-webapp/vendor-software-products-rest/vendor-software-products-rest-services/src/main/java/org/openecomp/sdcrests/vsp/rest/CatalogVspClient.java index 22e9b54099..6a1107cbec 100644 --- a/openecomp-be/api/openecomp-sdc-rest-webapp/vendor-software-products-rest/vendor-software-products-rest-services/src/main/java/org/openecomp/sdcrests/vsp/rest/CatalogVspClient.java +++ b/openecomp-be/api/openecomp-sdc-rest-webapp/vendor-software-products-rest/vendor-software-products-rest-services/src/main/java/org/openecomp/sdcrests/vsp/rest/CatalogVspClient.java @@ -22,6 +22,7 @@ package org.openecomp.sdcrests.vsp.rest; import java.util.Optional; +import org.openecomp.sdc.common.errors.CatalogRestClientException; public interface CatalogVspClient { @@ -31,5 +32,5 @@ public interface CatalogVspClient { * @param vspId the id of the vsp * @param user the user to perform the action */ - Optional findNameOfVfUsingVsp(String vspId, String user) throws Exception; + Optional findNameOfVfUsingVsp(String vspId, String user) throws CatalogRestClientException; } diff --git a/openecomp-be/api/openecomp-sdc-rest-webapp/vendor-software-products-rest/vendor-software-products-rest-services/src/main/java/org/openecomp/sdcrests/vsp/rest/exception/VendorSoftwareProductsExceptionSupplier.java b/openecomp-be/api/openecomp-sdc-rest-webapp/vendor-software-products-rest/vendor-software-products-rest-services/src/main/java/org/openecomp/sdcrests/vsp/rest/exception/VendorSoftwareProductsExceptionSupplier.java new file mode 100644 index 0000000000..10d897a28f --- /dev/null +++ b/openecomp-be/api/openecomp-sdc-rest-webapp/vendor-software-products-rest/vendor-software-products-rest-services/src/main/java/org/openecomp/sdcrests/vsp/rest/exception/VendorSoftwareProductsExceptionSupplier.java @@ -0,0 +1,91 @@ +/* + * - + * ============LICENSE_START======================================================= + * Copyright (C) 2022 Nordix Foundation. + * ================================================================================ + * 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. + * + * SPDX-License-Identifier: Apache-2.0 + * ============LICENSE_END========================================================= + */ + +package org.openecomp.sdcrests.vsp.rest.exception; + +import static org.openecomp.sdc.vendorsoftwareproduct.errors.VendorSoftwareProductErrorCodes.VSP_DELETE_ALREADY_IN_USE_BY_VF; +import static org.openecomp.sdc.vendorsoftwareproduct.errors.VendorSoftwareProductErrorCodes.VSP_DELETE_FROM_DATABASE_ERROR; +import static org.openecomp.sdc.vendorsoftwareproduct.errors.VendorSoftwareProductErrorCodes.VSP_DELETE_FROM_STORAGE_ERROR; +import static org.openecomp.sdc.vendorsoftwareproduct.errors.VendorSoftwareProductErrorCodes.VSP_DELETE_GENERIC_ERROR; +import static org.openecomp.sdc.vendorsoftwareproduct.errors.VendorSoftwareProductErrorCodes.VSP_DELETE_NOT_ARCHIVED; + +import java.util.function.Supplier; +import lombok.AccessLevel; +import lombok.NoArgsConstructor; +import org.openecomp.sdc.common.errors.CoreException; +import org.openecomp.sdc.common.errors.ErrorCategory; +import org.openecomp.sdc.common.errors.ErrorCode.ErrorCodeBuilder; +import org.openecomp.sdc.common.errors.Messages; +import org.openecomp.sdc.vendorsoftwareproduct.dao.errors.VendorSoftwareProductNotFoundErrorBuilder; + +@NoArgsConstructor(access = AccessLevel.PRIVATE) +public class VendorSoftwareProductsExceptionSupplier { + + public static Supplier vspNotFound(final String vspId) { + final VendorSoftwareProductNotFoundErrorBuilder errorBuilder = new VendorSoftwareProductNotFoundErrorBuilder(vspId); + return () -> new CoreException((errorBuilder.build())); + } + + public static Supplier vspInUseByVf(final String vfName) { + final String errorMsg = Messages.DELETE_VSP_ERROR_USED_BY_VF.formatMessage(vfName, vfName); + final ErrorCodeBuilder errorBuilder = + new ErrorCodeBuilder().withId(VSP_DELETE_ALREADY_IN_USE_BY_VF) + .withCategory(ErrorCategory.USER) + .withMessage(errorMsg); + return () -> new CoreException(errorBuilder.build()); + } + + public static Supplier deleteGenericError(final String vspId) { + final String errorMsg = String.format("An error has occurred while trying to delete the VSP '%s'.", vspId); + final ErrorCodeBuilder errorBuilder = + new ErrorCodeBuilder().withId(VSP_DELETE_GENERIC_ERROR) + .withCategory(ErrorCategory.SYSTEM) + .withMessage(errorMsg); + return () -> new CoreException(errorBuilder.build()); + } + + public static Supplier deleteNotArchivedVsp(final String vspId) { + final String errorMsg = Messages.DELETE_NOT_ARCHIVED_VSP_ERROR.formatMessage(vspId); + final ErrorCodeBuilder errorBuilder = + new ErrorCodeBuilder().withId(VSP_DELETE_NOT_ARCHIVED) + .withCategory(ErrorCategory.USER) + .withMessage(errorMsg); + return () -> new CoreException(errorBuilder.build()); + } + + public static Supplier deleteVspFromStorageFailure(final String vspId) { + final String errorMsg = Messages.DELETE_VSP_FROM_STORAGE_ERROR.formatMessage(vspId); + final ErrorCodeBuilder errorBuilder = + new ErrorCodeBuilder().withId(VSP_DELETE_FROM_STORAGE_ERROR) + .withCategory(ErrorCategory.SYSTEM) + .withMessage(errorMsg); + return () -> new CoreException(errorBuilder.build()); + } + + public static Supplier deleteVspFromDatabaseFailure(final String vspId) { + final String errorMsg = Messages.DELETE_VSP_ERROR.formatMessage(vspId); + final ErrorCodeBuilder errorBuilder = + new ErrorCodeBuilder().withId(VSP_DELETE_FROM_DATABASE_ERROR) + .withCategory(ErrorCategory.SYSTEM) + .withMessage(errorMsg); + return () -> new CoreException(errorBuilder.build()); + } +} diff --git a/openecomp-be/api/openecomp-sdc-rest-webapp/vendor-software-products-rest/vendor-software-products-rest-services/src/main/java/org/openecomp/sdcrests/vsp/rest/services/CatalogVspClientImpl.java b/openecomp-be/api/openecomp-sdc-rest-webapp/vendor-software-products-rest/vendor-software-products-rest-services/src/main/java/org/openecomp/sdcrests/vsp/rest/services/CatalogVspClientImpl.java index 221c3a7fc5..c9ad46850e 100644 --- a/openecomp-be/api/openecomp-sdc-rest-webapp/vendor-software-products-rest/vendor-software-products-rest-services/src/main/java/org/openecomp/sdcrests/vsp/rest/services/CatalogVspClientImpl.java +++ b/openecomp-be/api/openecomp-sdc-rest-webapp/vendor-software-products-rest/vendor-software-products-rest-services/src/main/java/org/openecomp/sdcrests/vsp/rest/services/CatalogVspClientImpl.java @@ -21,9 +21,14 @@ package org.openecomp.sdcrests.vsp.rest.services; +import static javax.ws.rs.core.HttpHeaders.ACCEPT; +import static javax.ws.rs.core.MediaType.APPLICATION_JSON; + import com.fasterxml.jackson.databind.ObjectMapper; +import java.util.Map; +import java.util.Optional; +import java.util.Properties; import org.jetbrains.annotations.Nullable; -import org.onap.sdc.tosca.services.YamlUtil; import org.openecomp.core.validation.errors.ErrorMessagesFormatBuilder; import org.openecomp.sdc.common.CommonConfigurationManager; import org.openecomp.sdc.common.api.Constants; @@ -33,32 +38,17 @@ import org.openecomp.sdc.common.http.client.api.HttpRequest; import org.openecomp.sdc.common.http.client.api.HttpResponse; import org.openecomp.sdc.logging.api.Logger; import org.openecomp.sdc.logging.api.LoggerFactory; -import org.openecomp.sdcrests.item.rest.services.catalog.notification.EntryNotConfiguredException; import org.openecomp.sdcrests.item.rest.services.catalog.notification.http.HttpConfiguration; import org.openecomp.sdcrests.vsp.rest.CatalogVspClient; -import java.io.FileInputStream; -import java.io.IOException; -import java.io.InputStream; -import java.util.Map; -import java.util.Objects; -import java.util.Optional; -import java.util.Properties; - -import static javax.ws.rs.core.HttpHeaders.ACCEPT; -import static javax.ws.rs.core.MediaType.APPLICATION_JSON; - public class CatalogVspClientImpl implements CatalogVspClient { private static final Logger LOGGER = LoggerFactory.getLogger(CatalogVspClientImpl.class); private static final String URL_GET_RESOURCE_BY_CSAR_UUID = "%s://%s:%s/sdc2/rest/v1/catalog/resources/csar/%s"; - private static final String CONFIG_FILE_PROPERTY = "configuration.yaml"; private static final String CONFIG_SECTION = "catalogNotificationsConfig"; public static final String NAME = "name"; public static final String SDC_2_REST_V_1_CATALOG_RESOURCES_CSAR_CSARUUID = "sdc2/rest/v1/catalog/resources/csar/{csaruuid}"; - public CatalogVspClientImpl() { } - /** * Returns the name of a VF which is using the provided VSP. * It returns an empty optional in case the VSP is not used by any VF, diff --git a/openecomp-be/api/openecomp-sdc-rest-webapp/vendor-software-products-rest/vendor-software-products-rest-services/src/main/java/org/openecomp/sdcrests/vsp/rest/services/VendorSoftwareProductsImpl.java b/openecomp-be/api/openecomp-sdc-rest-webapp/vendor-software-products-rest/vendor-software-products-rest-services/src/main/java/org/openecomp/sdcrests/vsp/rest/services/VendorSoftwareProductsImpl.java index 9bb68f23af..6431db3354 100644 --- a/openecomp-be/api/openecomp-sdc-rest-webapp/vendor-software-products-rest/vendor-software-products-rest-services/src/main/java/org/openecomp/sdcrests/vsp/rest/services/VendorSoftwareProductsImpl.java +++ b/openecomp-be/api/openecomp-sdc-rest-webapp/vendor-software-products-rest/vendor-software-products-rest-services/src/main/java/org/openecomp/sdcrests/vsp/rest/services/VendorSoftwareProductsImpl.java @@ -42,7 +42,6 @@ import javax.ws.rs.core.Response; import org.apache.commons.collections4.MapUtils; import org.openecomp.core.dao.UniqueValueDaoFactory; import org.openecomp.core.util.UniqueValueUtil; -import org.openecomp.core.validation.errors.ErrorMessagesFormatBuilder; import org.openecomp.sdc.activitylog.ActivityLogManager; import org.openecomp.sdc.activitylog.ActivityLogManagerFactory; import org.openecomp.sdc.activitylog.dao.type.ActivityLogEntity; @@ -101,6 +100,7 @@ import org.openecomp.sdcrests.vendorsoftwareproducts.types.VspDetailsDto; import org.openecomp.sdcrests.vendorsoftwareproducts.types.VspRequestDto; import org.openecomp.sdcrests.vsp.rest.CatalogVspClient; import org.openecomp.sdcrests.vsp.rest.VendorSoftwareProducts; +import org.openecomp.sdcrests.vsp.rest.exception.VendorSoftwareProductsExceptionSupplier; import org.openecomp.sdcrests.vsp.rest.mapping.MapComputeEntityToVspComputeDto; import org.openecomp.sdcrests.vsp.rest.mapping.MapItemToVspDetailsDto; import org.openecomp.sdcrests.vsp.rest.mapping.MapPackageInfoToPackageInfoDto; @@ -281,60 +281,100 @@ public class VendorSoftwareProductsImpl implements VendorSoftwareProducts { } @Override - public Response deleteVsp(String vspId, String user) { - Item vsp = itemManager.get(vspId); - if (!vsp.getType().equals(ItemType.vsp.name())) { - throw new CoreException((new ErrorCode.ErrorCodeBuilder().withMessage(String.format("Vsp with id %s does not exist.", vspId)).build())); + public Response deleteVsp(final String vspId, final String user) { + final Item vsp = itemManager.get(vspId); + if (!ItemType.vsp.getName().equals(vsp.getType())) { + throw VendorSoftwareProductsExceptionSupplier.vspNotFound(vspId).get(); } + + checkIfCanDeleteVsp(vsp, user); + try { - Optional optUsedInVf = catalogVspClient.findNameOfVfUsingVsp(vspId, user); - if (optUsedInVf.isPresent()) { - return Response.status(Response.Status.FORBIDDEN).entity( - new Exception(ErrorMessagesFormatBuilder.getErrorWithParameters(Messages.DELETE_VSP_ERROR_USED_BY_VF.getErrorMessage(), optUsedInVf.get(), optUsedInVf.get())) - ).build(); - } - } catch (Exception e) { - return Response.status(Response.Status.INTERNAL_SERVER_ERROR).entity(new CoreException((new ErrorCode.ErrorCodeBuilder().withMessage(String.format("Vsp with id %s cannot be deleted due to error %s.", vspId, e.getMessage())).build()))).build(); + deleteVspFromStorage(vspId, user); + } catch (final Exception e) { + logDeleteFromStorageFailure(vspId, user); + throw VendorSoftwareProductsExceptionSupplier.deleteVspFromStorageFailure(vspId).get(); } - Integer certifiedVersionsCounter = vsp.getVersionStatusCounters().get(VersionStatus.Certified); - final ArtifactStorageManager artifactStorageManager = storageFactory.createArtifactStorageManager(); - if (Objects.isNull(certifiedVersionsCounter) || certifiedVersionsCounter == 0) { - if (artifactStorageManager.isEnabled() && !deleteVspFromStorage(vspId, artifactStorageManager)) { - return Response.status(Response.Status.INTERNAL_SERVER_ERROR) - .entity(new Exception(Messages.DELETE_VSP_FROM_STORAGE_ERROR.formatMessage(vspId))).build(); - } - return deleteVsp(vspId, user, vsp); - } else { - final var isVspArchived = getVspList(null, ItemStatus.ARCHIVED.name(), user).stream().anyMatch(item -> item.getId().equals(vspId)); - if (isVspArchived) { - if (artifactStorageManager.isEnabled() && !deleteVspFromStorage(vspId, artifactStorageManager)) { - return Response.status(Response.Status.INTERNAL_SERVER_ERROR) - .entity(new Exception(Messages.DELETE_VSP_FROM_STORAGE_ERROR.formatMessage(vspId))).build(); - } - return deleteVsp(vspId, user, vsp); - } - return Response.status(Response.Status.FORBIDDEN).entity(new Exception(Messages.DELETE_VSP_ERROR.getErrorMessage())).build(); + try { + deleteVsp(vspId, user, vsp); + } catch (final Exception e) { + throw VendorSoftwareProductsExceptionSupplier.deleteVspFromDatabaseFailure(vspId).get(); + } + + return Response.ok().build(); + } + + private void checkIfCanDeleteVsp(final Item vsp, final String user) { + final String vspId = vsp.getId(); + + checkIfVspInUse(user, vspId); + + if (isVspItemNeverCertified(vsp)) { + return; + } + if (!isVspItemArchived(vspId, user)) { + throw VendorSoftwareProductsExceptionSupplier.deleteNotArchivedVsp(vspId).get(); } } - private boolean deleteVspFromStorage(final String vspId, final ArtifactStorageManager artifactStorageManager) { + private void checkIfVspInUse(final String user, final String vspId) { + final Optional vfNameThatUsesVspOpt; try { + vfNameThatUsesVspOpt = catalogVspClient.findNameOfVfUsingVsp(vspId, user); + } catch (final Exception e) { + throw VendorSoftwareProductsExceptionSupplier.deleteGenericError(vspId).get(); + } + if (vfNameThatUsesVspOpt.isPresent()) { + final String vfName = vfNameThatUsesVspOpt.get(); + throw VendorSoftwareProductsExceptionSupplier.vspInUseByVf(vfName).get(); + } + } + + private boolean isVspItemArchived(final String vspId, final String user) { + return getVspList(null, ItemStatus.ARCHIVED.name(), user).stream().anyMatch(item -> vspId.equals(item.getId())); + } + + private boolean isVspItemNeverCertified(final Item vsp) { + final Integer certifiedVersionsCounter = vsp.getVersionStatusCounters().get(VersionStatus.Certified); + return certifiedVersionsCounter == null || certifiedVersionsCounter == 0; + } + + private void deleteVspFromStorage(final String vspId, final String user) { + final ArtifactStorageManager artifactStorageManager = storageFactory.createArtifactStorageManager(); + if (artifactStorageManager.isEnabled()) { artifactStorageManager.delete(vspId); + logDeleteFromStorageAllSuccess(vspId, user); + } + } + + private void logDeleteFromStorageFailure(final String vspId, final String user) { + final String message = Messages.DELETE_VSP_FROM_STORAGE_ERROR.formatMessage(vspId); + try { + versioningManager.list(vspId).forEach(version -> activityLogManager.logActivity( + new ActivityLogEntity(vspId, version, ActivityType.Delete_From_Storage, user, false, message, message) + )); } catch (final Exception e) { - LOGGER.error("Failed to delete VSP '{}'", vspId, e); - return false; + LOGGER.error("Could not log activity '{}'", message, e); + } + } + private void logDeleteFromStorageAllSuccess(final String vspId, final String user) { + final String message = String.format("VSP '%s' fully deleted from the storage", vspId); + try { + versioningManager.list(vspId).forEach(version -> activityLogManager.logActivity( + new ActivityLogEntity(vspId, version, ActivityType.Delete_From_Storage, user, true, message, message) + )); + } catch (final Exception e) { + LOGGER.error("Could not log activity '{}'", message, e); } - return true; } - private Response deleteVsp(String vspId, String user, Item vsp) { + private void deleteVsp(final String vspId, final String user, final Item vsp) { versioningManager.list(vspId).forEach(version -> vendorSoftwareProductManager.deleteVsp(vspId, version)); itemManager.delete(vsp); permissionsManager.deleteItemPermissions(vspId); uniqueValueUtil.deleteUniqueValue(VENDOR_SOFTWARE_PRODUCT_NAME, vsp.getName()); notifyUsers(vspId, vsp.getName(), null, null, user, NotificationEventTypes.DELETE); - return Response.ok().build(); } @Override diff --git a/openecomp-be/api/openecomp-sdc-rest-webapp/vendor-software-products-rest/vendor-software-products-rest-services/src/test/java/org/openecomp/sdcrests/vsp/rest/services/OrchestrationTemplateCandidateImplTest.java b/openecomp-be/api/openecomp-sdc-rest-webapp/vendor-software-products-rest/vendor-software-products-rest-services/src/test/java/org/openecomp/sdcrests/vsp/rest/services/OrchestrationTemplateCandidateImplTest.java index 8fd160a886..bdd70ed589 100644 --- a/openecomp-be/api/openecomp-sdc-rest-webapp/vendor-software-products-rest/vendor-software-products-rest-services/src/test/java/org/openecomp/sdcrests/vsp/rest/services/OrchestrationTemplateCandidateImplTest.java +++ b/openecomp-be/api/openecomp-sdc-rest-webapp/vendor-software-products-rest/vendor-software-products-rest-services/src/test/java/org/openecomp/sdcrests/vsp/rest/services/OrchestrationTemplateCandidateImplTest.java @@ -399,24 +399,6 @@ class OrchestrationTemplateCandidateImplTest { .putUploadAsFinished(candidateId, versionId, vspUploadStatusDto.getLockId(), VspUploadStatus.ERROR, user); } -// @Test -// void uploadTestWithLatestStatusComplete() { -// final VspUploadStatusDto vspUploadStatusDto = new VspUploadStatusDto(); -// vspUploadStatusDto.setComplete(true); -// //given -// when(orchestrationTemplateCandidateUploadManager.findLatestStatus(candidateId, versionId, user)).thenReturn(Optional.of(vspUploadStatusDto)); -// final Attachment mock = Mockito.mock(Attachment.class); -// when(mock.getDataHandler()).thenReturn(Mockito.mock(DataHandler.class)); -// //when -// final CoreException actualException = assertThrows(CoreException.class, -// () -> orchestrationTemplateCandidate.upload(candidateId, versionId, mock, user)); -// final CoreException expectedException = couldNotAcceptPackageNoUploadInProgress(candidateId, versionId).get(); -// //then -// assertEquals(expectedException.code().id(), actualException.code().id()); -// assertEquals(expectedException.code().message(), actualException.code().message()); -// verify(orchestrationTemplateCandidateUploadManager).findLatestStatus(candidateId, versionId, user); -// } - @Test void uploadTestWithUploadInProgress() { final VspUploadStatusDto vspUploadStatusDto = new VspUploadStatusDto(); diff --git a/openecomp-be/api/openecomp-sdc-rest-webapp/vendor-software-products-rest/vendor-software-products-rest-services/src/test/java/org/openecomp/sdcrests/vsp/rest/services/VendorSoftwareProductsImplTest.java b/openecomp-be/api/openecomp-sdc-rest-webapp/vendor-software-products-rest/vendor-software-products-rest-services/src/test/java/org/openecomp/sdcrests/vsp/rest/services/VendorSoftwareProductsImplTest.java index 1936aaa7b4..76e4910a66 100644 --- a/openecomp-be/api/openecomp-sdc-rest-webapp/vendor-software-products-rest/vendor-software-products-rest-services/src/test/java/org/openecomp/sdcrests/vsp/rest/services/VendorSoftwareProductsImplTest.java +++ b/openecomp-be/api/openecomp-sdc-rest-webapp/vendor-software-products-rest/vendor-software-products-rest-services/src/test/java/org/openecomp/sdcrests/vsp/rest/services/VendorSoftwareProductsImplTest.java @@ -23,14 +23,17 @@ package org.openecomp.sdcrests.vsp.rest.services; import static ch.qos.logback.classic.util.ContextInitializer.CONFIG_FILE_PROPERTY; import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertFalse; import static org.junit.jupiter.api.Assertions.assertNull; +import static org.junit.jupiter.api.Assertions.assertThrows; +import static org.junit.jupiter.api.Assertions.assertTrue; import static org.mockito.ArgumentMatchers.any; import static org.mockito.ArgumentMatchers.anyString; import static org.mockito.Mockito.doThrow; +import static org.mockito.Mockito.times; +import static org.mockito.Mockito.verify; import static org.mockito.Mockito.when; import static org.mockito.MockitoAnnotations.openMocks; -import static org.openecomp.sdc.common.errors.Messages.DELETE_VSP_ERROR; -import static org.openecomp.sdc.common.errors.Messages.DELETE_VSP_ERROR_USED_BY_VF; import static org.openecomp.sdc.common.errors.Messages.DELETE_VSP_FROM_STORAGE_ERROR; import java.io.FileNotFoundException; @@ -44,22 +47,30 @@ import javax.ws.rs.core.Response; import org.apache.http.HttpStatus; import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; +import org.mockito.ArgumentCaptor; import org.mockito.InjectMocks; import org.mockito.Mock; import org.openecomp.core.util.UniqueValueUtil; import org.openecomp.sdc.activitylog.ActivityLogManager; +import org.openecomp.sdc.activitylog.dao.type.ActivityLogEntity; +import org.openecomp.sdc.activitylog.dao.type.ActivityType; import org.openecomp.sdc.be.csar.storage.ArtifactStorageManager; -import org.openecomp.sdc.common.errors.CoreException; import org.openecomp.sdc.be.csar.storage.StorageFactory; +import org.openecomp.sdc.common.errors.CatalogRestClientException; +import org.openecomp.sdc.common.errors.CoreException; +import org.openecomp.sdc.common.errors.ErrorCode; +import org.openecomp.sdc.datatypes.model.ItemType; import org.openecomp.sdc.itempermissions.PermissionsManager; import org.openecomp.sdc.notification.services.NotificationPropagationManager; import org.openecomp.sdc.vendorsoftwareproduct.VendorSoftwareProductManager; import org.openecomp.sdc.versioning.AsdcItemManager; import org.openecomp.sdc.versioning.VersioningManager; +import org.openecomp.sdc.versioning.dao.types.Version; import org.openecomp.sdc.versioning.dao.types.VersionStatus; import org.openecomp.sdc.versioning.types.Item; import org.openecomp.sdc.versioning.types.ItemStatus; import org.openecomp.sdcrests.vsp.rest.CatalogVspClient; +import org.openecomp.sdcrests.vsp.rest.exception.VendorSoftwareProductsExceptionSupplier; class VendorSoftwareProductsImplTest { @@ -103,7 +114,7 @@ class VendorSoftwareProductsImplTest { System.setProperty("configuration.yaml", Paths.get(testResourcesPath.toString(), "configuration.yaml").toAbsolutePath().toString()); item = new Item(); - item.setType("vsp"); + item.setType(ItemType.vsp.getName()); item.setId(vspId); when(itemManager.get(vspId)).thenReturn(item); when(storageFactory.createArtifactStorageManager()).thenReturn(artifactStorageManager); @@ -111,9 +122,10 @@ class VendorSoftwareProductsImplTest { @Test void deleteNotCertifiedVspOk() { - Response rsp = vendorSoftwareProducts.deleteVsp(vspId, user); - assertEquals(HttpStatus.SC_OK, rsp.getStatus()); - assertNull(rsp.getEntity()); + when(itemManager.list(any())).thenReturn(List.of(item)); + Response actualResponse = vendorSoftwareProducts.deleteVsp(vspId, user); + assertEquals(HttpStatus.SC_OK, actualResponse.getStatus()); + assertNull(actualResponse.getEntity()); } @Test @@ -128,10 +140,9 @@ class VendorSoftwareProductsImplTest { void deleteVspWithS3Fail() { when(artifactStorageManager.isEnabled()).thenReturn(true); doThrow(new RuntimeException()).when(artifactStorageManager).delete(anyString()); - Response rsp = vendorSoftwareProducts.deleteVsp(vspId, user); - assertEquals(HttpStatus.SC_INTERNAL_SERVER_ERROR, rsp.getStatus()); - assertEquals(rsp.getEntity().getClass(), Exception.class); - assertEquals(((Exception) rsp.getEntity()).getLocalizedMessage(), DELETE_VSP_FROM_STORAGE_ERROR.formatMessage(vspId)); + final CoreException actualException = assertThrows(CoreException.class, () -> vendorSoftwareProducts.deleteVsp(vspId, user)); + final CoreException expectedException = VendorSoftwareProductsExceptionSupplier.deleteVspFromStorageFailure(vspId).get(); + assertErrorCode(actualException.code(), expectedException.code()); } @Test @@ -139,10 +150,9 @@ class VendorSoftwareProductsImplTest { item.addVersionStatus(VersionStatus.Certified); when(itemManager.get(vspId)).thenReturn(item); - Response rsp = vendorSoftwareProducts.deleteVsp(vspId, user); - assertEquals(HttpStatus.SC_FORBIDDEN, rsp.getStatus()); - assertEquals(rsp.getEntity().getClass(), Exception.class); - assertEquals(((Exception) rsp.getEntity()).getLocalizedMessage(), DELETE_VSP_ERROR.getErrorMessage()); + final CoreException actualException = assertThrows(CoreException.class, () -> vendorSoftwareProducts.deleteVsp(vspId, user)); + final CoreException expectedException = VendorSoftwareProductsExceptionSupplier.deleteNotArchivedVsp(vspId).get(); + assertErrorCode(actualException.code(), expectedException.code()); } @Test @@ -158,65 +168,121 @@ class VendorSoftwareProductsImplTest { assertNull(rsp.getEntity()); } + @Test + void deleteCertifiedAndNotArchivedVsp() { + item.setStatus(ItemStatus.ACTIVE); + item.addVersionStatus(VersionStatus.Certified); + when(itemManager.get(vspId)).thenReturn(item); + + final CoreException actualException = assertThrows(CoreException.class, () -> vendorSoftwareProducts.deleteVsp(vspId, user)); + final CoreException expectedException = VendorSoftwareProductsExceptionSupplier.deleteNotArchivedVsp(vspId).get(); + assertErrorCode(actualException.code(), expectedException.code()); + } + + @Test + void deleteVspNotFoundTest() { + when(itemManager.get(vspId)).thenReturn(new Item()); + final CoreException actualException = assertThrows(CoreException.class, () -> vendorSoftwareProducts.deleteVsp(vspId, user)); + final CoreException expectedException = VendorSoftwareProductsExceptionSupplier.vspNotFound(vspId).get(); + assertEquals(expectedException.code().id(), actualException.code().id()); + assertEquals(expectedException.code().message(), actualException.code().message()); + } + @Test void deleteCertifiedArchivedVspWithS3OK() { when(artifactStorageManager.isEnabled()).thenReturn(true); item.setStatus(ItemStatus.ARCHIVED); item.addVersionStatus(VersionStatus.Certified); when(itemManager.get(vspId)).thenReturn(item); + + final Version version1 = new Version("version1Id"); + final Version version2 = new Version("version2Id"); + final List versionList = List.of(version1, version2); + when(versioningManager.list(vspId)).thenReturn(versionList); + when(itemManager.list(any())).thenReturn(List.of(item)); Response rsp = vendorSoftwareProducts.deleteVsp(vspId, user); assertEquals(HttpStatus.SC_OK, rsp.getStatus()); assertNull(rsp.getEntity()); + + final ArgumentCaptor logActivityArgument = ArgumentCaptor.forClass(ActivityLogEntity.class); + verify(activityLogManager, times(2)).logActivity(logActivityArgument.capture()); + final List logActivityArgumentList = logActivityArgument.getAllValues(); + assertEquals(versionList.size(), logActivityArgumentList.size()); + for (int i = 0; i < versionList.size(); i++) { + final Version expectedVersion = versionList.get(i); + final ActivityLogEntity actualLogActivityArgument = logActivityArgumentList.get(i); + assertTrue(actualLogActivityArgument.isSuccess()); + assertEquals(vspId, actualLogActivityArgument.getItemId()); + assertEquals(expectedVersion.getId(), actualLogActivityArgument.getVersionId()); + assertEquals(user, actualLogActivityArgument.getUser()); + assertEquals(ActivityType.Delete_From_Storage, actualLogActivityArgument.getType()); + } } @Test void deleteCertifiedArchivedVspWithS3Fail() { + //given when(artifactStorageManager.isEnabled()).thenReturn(true); doThrow(new RuntimeException()).when(artifactStorageManager).delete(anyString()); item.setStatus(ItemStatus.ARCHIVED); item.addVersionStatus(VersionStatus.Certified); when(itemManager.get(vspId)).thenReturn(item); when(itemManager.list(any())).thenReturn(List.of(item)); - Response rsp = vendorSoftwareProducts.deleteVsp(vspId, user); - assertEquals(HttpStatus.SC_INTERNAL_SERVER_ERROR, rsp.getStatus()); - assertEquals(rsp.getEntity().getClass(), Exception.class); - assertEquals(((Exception) rsp.getEntity()).getLocalizedMessage(), DELETE_VSP_FROM_STORAGE_ERROR.formatMessage(vspId)); + + final Version version1 = new Version("version1Id"); + final Version version2 = new Version("version2Id"); + final List versionList = List.of(version1, version2); + when(versioningManager.list(vspId)).thenReturn(versionList); + + //when + final CoreException actualException = assertThrows(CoreException.class, () -> vendorSoftwareProducts.deleteVsp(vspId, user)); + + //then + final CoreException expectedException = VendorSoftwareProductsExceptionSupplier.deleteVspFromStorageFailure(vspId).get(); + assertErrorCode(actualException.code(), expectedException.code()); + + final ArgumentCaptor logActivityArgument = ArgumentCaptor.forClass(ActivityLogEntity.class); + verify(activityLogManager, times(2)).logActivity(logActivityArgument.capture()); + final List logActivityArgumentList = logActivityArgument.getAllValues(); + assertEquals(versionList.size(), logActivityArgumentList.size()); + for (int i = 0; i < versionList.size(); i++) { + final Version expectedVersion = versionList.get(i); + final ActivityLogEntity actualLogActivityArgument = logActivityArgumentList.get(i); + assertFalse(actualLogActivityArgument.isSuccess()); + assertEquals(vspId, actualLogActivityArgument.getItemId()); + assertEquals(expectedVersion.getId(), actualLogActivityArgument.getVersionId()); + assertEquals(user, actualLogActivityArgument.getUser()); + assertEquals(ActivityType.Delete_From_Storage, actualLogActivityArgument.getType()); + assertEquals(DELETE_VSP_FROM_STORAGE_ERROR.formatMessage(vspId), actualLogActivityArgument.getMessage()); + assertEquals(DELETE_VSP_FROM_STORAGE_ERROR.formatMessage(vspId), actualLogActivityArgument.getComment()); + } } @Test - void deleteVspUsedInVfKo() throws Exception { - Item item = new Item(); - item.setType("vsp"); - item.setId(vspId); + void deleteVspUsedInVfKo() { item.addVersionStatus(VersionStatus.Certified); when(itemManager.get(vspId)).thenReturn(item); when(catalogVspClient.findNameOfVfUsingVsp(vspId, user)).thenReturn(Optional.of(VF_NAME)); - Response rsp = vendorSoftwareProducts.deleteVsp(vspId, user); - assertEquals(HttpStatus.SC_FORBIDDEN, rsp.getStatus()); - assertEquals(rsp.getEntity().getClass(), Exception.class); - assertEquals(((Exception)rsp.getEntity()).getLocalizedMessage(), String.format(DELETE_VSP_ERROR_USED_BY_VF.getErrorMessage(), VF_NAME, VF_NAME)); + final CoreException actualException = assertThrows(CoreException.class, () -> vendorSoftwareProducts.deleteVsp(vspId, user)); + final CoreException expectedException = VendorSoftwareProductsExceptionSupplier.vspInUseByVf(VF_NAME).get(); + assertErrorCode(actualException.code(), expectedException.code()); } @Test - void deleteVspUsedInVfThrowsExceptionKo() throws Exception { - Item item = new Item(); - item.setType("vsp"); - item.setId(vspId); + void deleteVspUsedInVfThrowsExceptionKo() { item.addVersionStatus(VersionStatus.Certified); when(itemManager.get(vspId)).thenReturn(item); - final String vf_name = "Vf_name"; - when(catalogVspClient.findNameOfVfUsingVsp(vspId, user)).thenThrow(new Exception(SOME_INTERNAL_ERROR)); + when(catalogVspClient.findNameOfVfUsingVsp(vspId, user)).thenThrow(new CatalogRestClientException(SOME_INTERNAL_ERROR)); - Response rsp = vendorSoftwareProducts.deleteVsp(vspId, user); - assertEquals(HttpStatus.SC_INTERNAL_SERVER_ERROR, rsp.getStatus()); - assertEquals(rsp.getEntity().getClass(), CoreException.class); - assertEquals(((Exception)rsp.getEntity()).getLocalizedMessage(), String.format("Vsp with id %s cannot be deleted due to error %s.", vspId, SOME_INTERNAL_ERROR)); + final CoreException actualException = assertThrows(CoreException.class, () -> vendorSoftwareProducts.deleteVsp(vspId, user)); + final CoreException expectedException = VendorSoftwareProductsExceptionSupplier.deleteGenericError(vspId).get(); + assertErrorCode(actualException.code(), expectedException.code()); } @Test - void deleteCertifiedArchivedVspNotInVfOk() throws Exception { + void deleteCertifiedArchivedVspNotInVfOk() throws FileNotFoundException { String configPath = getConfigPath("configuration.yaml"); System.setProperty(CONFIG_FILE_PROPERTY, configPath); Item item = new Item(); @@ -240,4 +306,11 @@ class VendorSoftwareProductsImplTest { } return resource.getPath(); } + + private void assertErrorCode(final ErrorCode actualErrorCode, final ErrorCode expectedErrorCode) { + assertEquals(expectedErrorCode.id(), actualErrorCode.id()); + assertEquals(expectedErrorCode.category(), actualErrorCode.category()); + assertEquals(expectedErrorCode.message(), actualErrorCode.message()); + } + } -- cgit 1.2.3-korg