Log partial VSP deletion 19/128119/9
authorandre.schmid <andre.schmid@est.tech>
Thu, 24 Mar 2022 13:11:04 +0000 (13:11 +0000)
committerMichael Morris <michael.morris@est.tech>
Mon, 4 Apr 2022 15:25:41 +0000 (15:25 +0000)
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 <andre.schmid@est.tech>
14 files changed:
openecomp-be/api/openecomp-sdc-rest-webapp/openecomp-sdc-common-rest/src/main/java/org/openecomp/sdcrests/errors/DefaultExceptionMapper.java
openecomp-be/api/openecomp-sdc-rest-webapp/openecomp-sdc-common-rest/src/main/resources/errorCodesToResponseStatusMapping.json
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
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 with mode: 0644]
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
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
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
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
openecomp-be/lib/openecomp-common-lib/src/main/java/org/openecomp/sdc/common/errors/Messages.java
openecomp-be/lib/openecomp-sdc-activity-log-lib/openecomp-sdc-activity-log-api/src/main/java/org/openecomp/sdc/activitylog/dao/type/ActivityType.java
openecomp-be/lib/openecomp-sdc-datatypes-lib/src/main/java/org/openecomp/sdc/datatypes/model/ItemType.java
openecomp-be/lib/openecomp-sdc-vendor-software-product-lib/openecomp-sdc-vendor-software-product-core/src/main/java/org/openecomp/sdc/vendorsoftwareproduct/dao/errors/VendorSoftwareProductNotFoundErrorBuilder.java
openecomp-be/lib/openecomp-sdc-vendor-software-product-lib/openecomp-sdc-vendor-software-product-core/src/main/java/org/openecomp/sdc/vendorsoftwareproduct/errors/VendorSoftwareProductErrorCodes.java
openecomp-be/lib/openecomp-sdc-vendor-software-product-lib/openecomp-sdc-vendor-software-product-core/src/test/java/org/openecomp/sdc/vendorsoftwareproduct/dao/errors/VendorSoftwareProductNotFoundErrorBuilderTest.java

index a256af7..22d6d90 100644 (file)
@@ -80,8 +80,8 @@ public class DefaultExceptionMapper implements ExceptionMapper<Exception> {
         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) {
index 96c06ae..5b2e808 100644 (file)
@@ -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",
index 22e9b54..6a1107c 100644 (file)
@@ -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<String> findNameOfVfUsingVsp(String vspId, String user) throws Exception;
+    Optional<String> 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 (file)
index 0000000..10d897a
--- /dev/null
@@ -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<CoreException> vspNotFound(final String vspId) {
+        final VendorSoftwareProductNotFoundErrorBuilder errorBuilder = new VendorSoftwareProductNotFoundErrorBuilder(vspId);
+        return () -> new CoreException((errorBuilder.build()));
+    }
+
+    public static Supplier<CoreException> 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<CoreException> 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<CoreException> 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<CoreException> 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<CoreException> 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());
+    }
+}
index 221c3a7..c9ad468 100644 (file)
 
 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,
index 9bb68f2..6431db3 100644 (file)
@@ -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<String> 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<String> 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
index 8fd160a..bdd70ed 100644 (file)
@@ -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();
index 1936aaa..76e4910 100644 (file)
@@ -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<Version> 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<ActivityLogEntity> logActivityArgument = ArgumentCaptor.forClass(ActivityLogEntity.class);
+        verify(activityLogManager, times(2)).logActivity(logActivityArgument.capture());
+        final List<ActivityLogEntity> 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<Version> 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<ActivityLogEntity> logActivityArgument = ArgumentCaptor.forClass(ActivityLogEntity.class);
+        verify(activityLogManager, times(2)).logActivity(logActivityArgument.capture());
+        final List<ActivityLogEntity> 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());
+    }
+
 }
index 2ed67b3..2b97335 100644 (file)
@@ -96,9 +96,13 @@ public enum Messages {
     SUB_ENTITY_NOT_FOUND("Incorrect sub entity details provided."),
     FAILED_TO_SYNC("Non existing version cannot be synced."),
     FAILED_TO_PUBLISH_OUT_OF_SYNC("Publish is not allowed since the version status is Out of sync"),
-    DELETE_VSP_ERROR("Certified VSP must be archived before it can be deleted."),
+    DELETE_VSP_ERROR("Failed to delete VSP '%s' from database"),
+    DELETE_CERTIFIED_VSP_ERROR("Certified VSP '%s' must be archived before it can be deleted."),
     DELETE_VSP_ERROR_USED_BY_VF("VSP cannot be deleted as it is used by VF %s. The VSP will only be available for deletion if VF %s is deleted."),
     DELETE_VSP_UNEXPECTED_ERROR_USED_BY_VF("An error occurred while retrieving the usage of VSP %s through the rest endpoint %s"),
+    VSP_NOT_FOUND("Vendor Software Product with id '%s' was not found."),
+    VSP_VERSION_NOT_FOUND("Vendor Software Product with id '%s' and version id '%s' was not found."),
+    DELETE_NOT_ARCHIVED_VSP_ERROR("The certified VSP '%s' must be archived before it can be deleted."),
     DELETE_VSP_FROM_STORAGE_ERROR("Failed to delete VSP '%s' from Storage"),
     DELETE_VLM_ERROR("VLM has been certified and cannot be deleted."),
     DELETE_VSP_ARCHIVED_ERROR("VSP has not been archived and cannot be deleted."),
index ff4bfd9..4968a90 100644 (file)
  */
 package org.openecomp.sdc.datatypes.model;
 
-public enum ItemType {vlm, vsp}
+import lombok.AllArgsConstructor;
+import lombok.Getter;
+
+@AllArgsConstructor
+public enum ItemType {
+    vlm("vlm"), vsp("vsp");
+
+    @Getter
+    private final String name;
+
+}
index 5b0933d..3d6180c 100644 (file)
@@ -23,11 +23,10 @@ import static org.openecomp.sdc.vendorsoftwareproduct.errors.VendorSoftwareProdu
 
 import org.openecomp.sdc.common.errors.ErrorCategory;
 import org.openecomp.sdc.common.errors.ErrorCode;
+import org.openecomp.sdc.common.errors.Messages;
 
 public class VendorSoftwareProductNotFoundErrorBuilder {
 
-    private static final String VSP_FOUND_MSG = "Vendor software product with Id %s not found.";
-    private static final String VSP_ID_AND_VERSION_ID_NOT_FOUND_MSG = "Vendor Software Product with id '%s' and version id '%s' not found.";
     private final ErrorCode.ErrorCodeBuilder builder = new ErrorCode.ErrorCodeBuilder();
 
     /**
@@ -38,13 +37,13 @@ public class VendorSoftwareProductNotFoundErrorBuilder {
     public VendorSoftwareProductNotFoundErrorBuilder(String vendorSoftwareProductId) {
         builder.withId(VSP_NOT_FOUND);
         builder.withCategory(ErrorCategory.APPLICATION);
-        builder.withMessage(String.format(VSP_FOUND_MSG, vendorSoftwareProductId));
+        builder.withMessage(Messages.VSP_NOT_FOUND.formatMessage(vendorSoftwareProductId));
     }
 
     public VendorSoftwareProductNotFoundErrorBuilder(final String vendorSoftwareProductId, final String vendorSoftwareProductVersionId) {
         builder.withId(VSP_NOT_FOUND);
         builder.withCategory(ErrorCategory.APPLICATION);
-        builder.withMessage(String.format(VSP_ID_AND_VERSION_ID_NOT_FOUND_MSG, vendorSoftwareProductId, vendorSoftwareProductVersionId));
+        builder.withMessage(Messages.VSP_VERSION_NOT_FOUND.formatMessage(vendorSoftwareProductId, vendorSoftwareProductVersionId));
     }
 
     public ErrorCode build() {
index 21b2cae..ab43fdc 100644 (file)
@@ -85,6 +85,11 @@ public class VendorSoftwareProductErrorCodes {
     public static final String VSP_UPLOAD_STATUS_NOT_FOUND_ERROR = "VSP_UPLOAD_STATUS_NOT_FOUND_ERROR";
     public static final String VSP_UPLOAD_ALREADY_FINISHED_ERROR = "VSP_UPLOAD_ALREADY_FINISHED_ERROR";
     public static final String VSP_UPLOAD_ALREADY_IN_STATUS_ERROR = "VSP_UPLOAD_ALREADY_IN_STATUS_ERROR";
+    public static final String VSP_DELETE_ALREADY_IN_USE_BY_VF = "VSP_DELETE_ALREADY_IN_USE_BY_VF";
+    public static final String VSP_DELETE_NOT_ARCHIVED = "VSP_DELETE_NOT_ARCHIVED";
+    public static final String VSP_DELETE_GENERIC_ERROR = "VSP_DELETE_GENERIC_ERROR";
+    public static final String VSP_DELETE_FROM_STORAGE_ERROR = "VSP_DELETE_FROM_STORAGE_ERROR";
+    public static final String VSP_DELETE_FROM_DATABASE_ERROR = "VSP_DELETE_FROM_DATABASE_ERROR";
 
     private VendorSoftwareProductErrorCodes() {
     }
index 71b77b1..0086dd0 100644 (file)
@@ -16,6 +16,7 @@
 package org.openecomp.sdc.vendorsoftwareproduct.dao.errors;
 
 import static org.junit.jupiter.api.Assertions.assertEquals;
+import static org.openecomp.sdc.common.errors.Messages.VSP_VERSION_NOT_FOUND;
 import static org.openecomp.sdc.vendorsoftwareproduct.errors.VendorSoftwareProductErrorCodes.VSP_NOT_FOUND;
 
 import org.junit.jupiter.api.Test;
@@ -40,7 +41,7 @@ class VendorSoftwareProductNotFoundErrorBuilderTest {
         final ErrorCode actualErrorCode = errorBuilder.build();
         assertEquals(ErrorCategory.APPLICATION, actualErrorCode.category());
         assertEquals(VSP_NOT_FOUND, actualErrorCode.id());
-        final String expectedMsg = String.format("Vendor Software Product with id '%s' and version id '%s' not found.", vspId, vspVersionId);
+        final String expectedMsg = VSP_VERSION_NOT_FOUND.formatMessage(vspId, vspVersionId);
         assertEquals(expectedMsg, actualErrorCode.message());
     }
 }