From 1ff5cd3de7ccc52adf0f4cbdf9c7ab511bd5c4a5 Mon Sep 17 00:00:00 2001 From: JvD_Ericsson Date: Tue, 29 Mar 2022 13:41:35 +0100 Subject: Support deletion of archived services in SDC BE Issue-ID: SDC-3936 Change-Id: I75201007c9cf6b71b035f14864e380d78aace12b Signed-off-by: JvD_Ericsson --- .../files/default/error-configuration.yaml | 15 ++++++++ .../be/components/impl/ServiceBusinessLogic.java | 41 ++++++++++++++++++++-- .../openecomp/sdc/be/servlets/ServiceServlet.java | 18 ++++++++-- 3 files changed, 70 insertions(+), 4 deletions(-) (limited to 'catalog-be/src/main') diff --git a/catalog-be/src/main/docker/backend/chef-repo/cookbooks/sdc-catalog-be/files/default/error-configuration.yaml b/catalog-be/src/main/docker/backend/chef-repo/cookbooks/sdc-catalog-be/files/default/error-configuration.yaml index 10cc6f6712..9e7939d58b 100644 --- a/catalog-be/src/main/docker/backend/chef-repo/cookbooks/sdc-catalog-be/files/default/error-configuration.yaml +++ b/catalog-be/src/main/docker/backend/chef-repo/cookbooks/sdc-catalog-be/files/default/error-configuration.yaml @@ -2635,6 +2635,21 @@ errors: messageId: "SVC4163" } + #---------SVC4164----------------------------- + # %1 - Component name + COMPONENT_NOT_ARCHIVED: { + code: 403, + message: "Component '%1' is not archived", + messageId: "SVC4692" + } + + #---------SVC4165----------------------------- + # %1 - List of services + COMPONENT_IN_USE_BY_ANOTHER_COMPONENT: { + code: 403, + message: "Component is in use by '%1'", + messageId: "SVC4693" + } #---------SVC4164----------------------------- # %1 - componentType # %2 - component name diff --git a/catalog-be/src/main/java/org/openecomp/sdc/be/components/impl/ServiceBusinessLogic.java b/catalog-be/src/main/java/org/openecomp/sdc/be/components/impl/ServiceBusinessLogic.java index aa011e91f4..8dac6ffc08 100644 --- a/catalog-be/src/main/java/org/openecomp/sdc/be/components/impl/ServiceBusinessLogic.java +++ b/catalog-be/src/main/java/org/openecomp/sdc/be/components/impl/ServiceBusinessLogic.java @@ -102,6 +102,7 @@ import org.openecomp.sdc.be.datatypes.enums.ComponentTypeEnum; import org.openecomp.sdc.be.datatypes.enums.JsonPresentationFields; import org.openecomp.sdc.be.datatypes.enums.NodeTypeEnum; import org.openecomp.sdc.be.datatypes.enums.OriginTypeEnum; +import org.openecomp.sdc.be.datatypes.enums.ModelTypeEnum; import org.openecomp.sdc.be.externalapi.servlet.representation.ServiceDistributionReqInfo; import org.openecomp.sdc.be.impl.ForwardingPathUtils; import org.openecomp.sdc.be.impl.WebAppContextWrapper; @@ -123,6 +124,7 @@ import org.openecomp.sdc.be.model.PropertyDefinition; import org.openecomp.sdc.be.model.Resource; import org.openecomp.sdc.be.model.Service; import org.openecomp.sdc.be.model.User; +import org.openecomp.sdc.be.model.Model; import org.openecomp.sdc.be.model.category.CategoryDefinition; import org.openecomp.sdc.be.model.jsonjanusgraph.operations.ArtifactsOperations; import org.openecomp.sdc.be.model.jsonjanusgraph.operations.ForwardingPathOperation; @@ -133,6 +135,7 @@ import org.openecomp.sdc.be.model.operations.api.IGroupOperation; import org.openecomp.sdc.be.model.operations.api.IGroupTypeOperation; import org.openecomp.sdc.be.model.operations.api.StorageOperationStatus; import org.openecomp.sdc.be.model.operations.impl.InterfaceLifecycleOperation; +import org.openecomp.sdc.be.model.operations.impl.ModelOperation; import org.openecomp.sdc.be.model.operations.impl.UniqueIdBuilder; import org.openecomp.sdc.be.model.operations.utils.ComponentValidationUtils; import org.openecomp.sdc.be.plugins.ServiceCreationPlugin; @@ -194,6 +197,7 @@ public class ServiceBusinessLogic extends ComponentBusinessLogic { private ServiceCategoryValidator serviceCategoryValidator; @Autowired private ServiceValidator serviceValidator; + private final ModelOperation modelOperation; @Autowired public ServiceBusinessLogic(IElementOperation elementDao, IGroupOperation groupOperation, IGroupInstanceOperation groupInstanceOperation, @@ -205,7 +209,7 @@ public class ServiceBusinessLogic extends ComponentBusinessLogic { ComponentContactIdValidator componentContactIdValidator, ComponentNameValidator componentNameValidator, ComponentTagsValidator componentTagsValidator, ComponentValidator componentValidator, ComponentIconValidator componentIconValidator, ComponentProjectCodeValidator componentProjectCodeValidator, - ComponentDescriptionValidator componentDescriptionValidator) { + ComponentDescriptionValidator componentDescriptionValidator, ModelOperation modelOperation) { super(elementDao, groupOperation, groupInstanceOperation, groupTypeOperation, groupBusinessLogic, interfaceOperation, interfaceLifecycleTypeOperation, artifactsBusinessLogic, artifactToscaOperation, componentContactIdValidator, componentNameValidator, componentTagsValidator, componentValidator, componentIconValidator, componentProjectCodeValidator, componentDescriptionValidator); @@ -214,6 +218,7 @@ public class ServiceBusinessLogic extends ComponentBusinessLogic { this.serviceDistributionValidation = serviceDistributionValidation; this.forwardingPathValidator = forwardingPathValidator; this.uiComponentDataConverter = uiComponentDataConverter; + this.modelOperation = modelOperation; } @Autowired @@ -1301,7 +1306,39 @@ public class ServiceBusinessLogic extends ComponentBusinessLogic { return Either.left(serviceRelations); } - public ResponseFormat deleteService(String serviceId, User user) { + public void deleteServiceAllVersions(String serviceId, User user) { + validateUserExists(user); + Either serviceStatus = toscaOperationFacade.getToscaElement(serviceId); + if (serviceStatus.isRight()) { + log.debug("Failed to get service {}", serviceId); + componentException(serviceStatus.right().value()); + } + Service service = serviceStatus.left().value(); + if (Boolean.FALSE.equals(service.isArchived())) { + log.debug("The service, {}, requested for delete has not been archived.", serviceId); + throw new ComponentException(ActionStatus.COMPONENT_NOT_ARCHIVED, serviceId); + } + List deletedServiceList = new ArrayList<>(); + try { + String model = service.getModel(); + final Optional modelOptional = modelOperation.findModelByName(model); + deletedServiceList = toscaOperationFacade.deleteService(service.getInvariantUUID(), true); + if (log.isDebugEnabled()) { + deletedServiceList.forEach(deletedS -> log.debug("Component {} was deleted.", deletedS)); + } + if (modelOptional.isPresent() && modelOptional.get().getModelType() == ModelTypeEnum.NORMATIVE_EXTENSION) { + modelOperation.deleteModel(modelOptional.get(), false); + } + toscaOperationFacade.commitAndCheck(service.getUniqueId()); + updateCatalog(service, ChangeTypeEnum.DELETE); + } catch (ComponentException exception) { + log.debug("Failed to delete service, {}, in ServiceServlet", serviceId); + janusGraphDao.rollback(); + throw exception; + } + } + + public ResponseFormat markServiceForDeletion(String serviceId, User user) { ResponseFormat responseFormat; validateUserExists(user); Either serviceStatus = toscaOperationFacade.getToscaElement(serviceId); diff --git a/catalog-be/src/main/java/org/openecomp/sdc/be/servlets/ServiceServlet.java b/catalog-be/src/main/java/org/openecomp/sdc/be/servlets/ServiceServlet.java index bf171c2042..bcedc60d40 100644 --- a/catalog-be/src/main/java/org/openecomp/sdc/be/servlets/ServiceServlet.java +++ b/catalog-be/src/main/java/org/openecomp/sdc/be/servlets/ServiceServlet.java @@ -52,6 +52,7 @@ import javax.ws.rs.POST; import javax.ws.rs.PUT; import javax.ws.rs.Path; import javax.ws.rs.PathParam; +import javax.ws.rs.QueryParam; import javax.ws.rs.Produces; import javax.ws.rs.core.Context; import javax.ws.rs.core.MediaType; @@ -109,6 +110,8 @@ public class ServiceServlet extends AbstractValidationsServlet { private final ElementBusinessLogic elementBusinessLogic; private final ServiceBusinessLogic serviceBusinessLogic; + public enum Action {DELETE, MARK_AS_DELETE} + @Inject public ServiceServlet(UserBusinessLogic userBusinessLogic, ComponentInstanceBusinessLogic componentInstanceBL, ComponentsUtils componentsUtils, ServletUtils servletUtils, ResourceImportManager resourceImportManager, ServiceBusinessLogic serviceBusinessLogic, @@ -269,7 +272,12 @@ public class ServiceServlet extends AbstractValidationsServlet { @ApiResponse(responseCode = "400", description = "Invalid content / Missing content"), @ApiResponse(responseCode = "404", description = "Service not found")}) @PermissionAllowed(AafPermission.PermNames.INTERNAL_ALL_VALUE) - public Response deleteService(@PathParam("serviceId") final String serviceId, @Context final HttpServletRequest request) { + public Response deleteService(@PathParam("serviceId") final String serviceId, + @Parameter(description = "Optional parameter to determine the delete action: " + + "DELETE, which will permanently delete theService from the system or " + + "MARK_AS_DELETE, which will logically mark the service as deleted. Default action is to MARK_AS_DELETE") + @QueryParam("deleteAction") final Action deleteAction, + @Context final HttpServletRequest request) { ServletContext context = request.getSession().getServletContext(); String url = request.getMethod() + " " + request.getRequestURI(); log.debug(START_HANDLE_REQUEST_OF, url); @@ -284,7 +292,13 @@ public class ServiceServlet extends AbstractValidationsServlet { .log(LoggerSupportabilityActions.DELETE_SERVICE, StatusCode.STARTED, "Starting to delete service {} by user {} ", serviceIdLower, userId); ServiceBusinessLogic businessLogic = getServiceBL(context); - ResponseFormat actionResponse = businessLogic.deleteService(serviceIdLower, modifier); + ResponseFormat actionResponse; + if (Action.DELETE.equals(deleteAction)) { + businessLogic.deleteServiceAllVersions(serviceIdLower, modifier); + actionResponse = componentsUtils.getResponseFormat(ActionStatus.NO_CONTENT); + } else { + actionResponse = businessLogic.markServiceForDeletion(serviceIdLower, modifier); + } if (actionResponse.getStatus() != HttpStatus.SC_NO_CONTENT) { log.debug("failed to delete service"); return buildErrorResponse(actionResponse); -- cgit 1.2.3-korg