diff --git a/src/main/resources/interface-specification.yml b/src/main/resources/interface-specification.yml index ff5e4f2a..4becb779 100644 --- a/src/main/resources/interface-specification.yml +++ b/src/main/resources/interface-specification.yml @@ -264,6 +264,12 @@ paths: application/problem+json: schema: $ref: '#/components/schemas/Problem' + '409': + description: E-Service has some descriptors + content: + application/problem+json: + schema: + $ref: '#/components/schemas/Problem' /eservices/{eServiceId}/consumers: parameters: - $ref: '#/components/parameters/CorrelationIdHeader' diff --git a/src/main/scala/it/pagopa/interop/catalogprocess/api/impl/ResponseHandlers.scala b/src/main/scala/it/pagopa/interop/catalogprocess/api/impl/ResponseHandlers.scala index ec6ced1a..cc5ebcad 100644 --- a/src/main/scala/it/pagopa/interop/catalogprocess/api/impl/ResponseHandlers.scala +++ b/src/main/scala/it/pagopa/interop/catalogprocess/api/impl/ResponseHandlers.scala @@ -102,10 +102,11 @@ object ResponseHandlers extends AkkaResponses { success: T => Route )(result: Try[T])(implicit contexts: Seq[(String, String)], logger: LoggerTakingImplicit[ContextFieldsToLog]): Route = result match { - case Success(s) => success(s) - case Failure(ex: OperationForbidden.type) => forbidden(ex, logMessage) - case Failure(ex: EServiceNotFound) => notFound(ex, logMessage) - case Failure(ex) => internalServerError(ex, logMessage) + case Success(s) => success(s) + case Failure(ex: OperationForbidden.type) => forbidden(ex, logMessage) + case Failure(ex: EServiceNotFound) => notFound(ex, logMessage) + case Failure(ex: EServiceWithDescriptorsNotDeletable) => conflict(ex, logMessage) + case Failure(ex) => internalServerError(ex, logMessage) } def activateDescriptorResponse[T](logMessage: String)( diff --git a/src/main/scala/it/pagopa/interop/catalogprocess/errors/CatalogProcessErrors.scala b/src/main/scala/it/pagopa/interop/catalogprocess/errors/CatalogProcessErrors.scala index 484ce0db..a5b71725 100644 --- a/src/main/scala/it/pagopa/interop/catalogprocess/errors/CatalogProcessErrors.scala +++ b/src/main/scala/it/pagopa/interop/catalogprocess/errors/CatalogProcessErrors.scala @@ -76,7 +76,10 @@ object CatalogProcessErrors { final case class AttributeNotFound(attributeId: UUID) extends ComponentError("0020", s"Attribute ${attributeId.toString} not found") + final case class EServiceWithDescriptorsNotDeletable(eServiceId: String) + extends ComponentError("0021", s"EService $eServiceId contains descriptors and cannot be deleted") + final case class InterfaceAlreadyExists(descriptorId: UUID) - extends ComponentError("0021", s"Descriptor ${descriptorId.toString} already has an interface") + extends ComponentError("0022", s"Descriptor ${descriptorId.toString} already has an interface") } diff --git a/src/main/scala/it/pagopa/interop/catalogprocess/service/impl/CatalogManagementServiceImpl.scala b/src/main/scala/it/pagopa/interop/catalogprocess/service/impl/CatalogManagementServiceImpl.scala index 74243985..1b59ce00 100644 --- a/src/main/scala/it/pagopa/interop/catalogprocess/service/impl/CatalogManagementServiceImpl.scala +++ b/src/main/scala/it/pagopa/interop/catalogprocess/service/impl/CatalogManagementServiceImpl.scala @@ -20,7 +20,8 @@ import it.pagopa.interop.catalogprocess.errors.CatalogProcessErrors.{ DescriptorDocumentNotFound, EServiceDescriptorNotFound, EServiceNotFound, - EServiceRiskAnalysisNotFound + EServiceRiskAnalysisNotFound, + EServiceWithDescriptorsNotDeletable } import it.pagopa.interop.commons.logging.{CanLogContextFields, ContextFieldsToLog} @@ -74,6 +75,7 @@ final case class CatalogManagementServiceImpl(invoker: CatalogManagementInvoker, invoker.invoke(request, s"E-Service $eServiceId deleted").recoverWith { case err: ApiError[_] if err.code == 404 => Future.failed(EServiceNotFound(eServiceId)) + case err: ApiError[_] if err.code == 409 => Future.failed(EServiceWithDescriptorsNotDeletable(eServiceId)) } } diff --git a/src/test/scala/it/pagopa/interop/catalogprocess/CatalogProcessSpec.scala b/src/test/scala/it/pagopa/interop/catalogprocess/CatalogProcessSpec.scala index 04ecaf6e..bb1e658b 100644 --- a/src/test/scala/it/pagopa/interop/catalogprocess/CatalogProcessSpec.scala +++ b/src/test/scala/it/pagopa/interop/catalogprocess/CatalogProcessSpec.scala @@ -18,7 +18,8 @@ import it.pagopa.interop.catalogprocess.errors.CatalogProcessErrors.{ DescriptorDocumentNotFound, EServiceNotFound, EServiceRiskAnalysisNotFound, - AttributeNotFound + AttributeNotFound, + EServiceWithDescriptorsNotDeletable } import it.pagopa.interop.catalogprocess.model._ import it.pagopa.interop.commons.cqrs.service.ReadModelService @@ -2378,14 +2379,12 @@ class CatalogProcessSpec extends SpecHelper with AnyWordSpecLike with ScalatestR "EService deletion" should { "succeed" in { - val requesterId = UUID.randomUUID() - val descriptorId = UUID.randomUUID() + val requesterId = UUID.randomUUID() + implicit val context: Seq[(String, String)] = Seq("bearer" -> bearerToken, USER_ROLES -> "admin", ORGANIZATION_ID_CLAIM -> requesterId.toString) - val descriptor = SpecData.catalogDescriptor.copy(id = descriptorId) - - val eService = SpecData.catalogItem.copy(descriptors = Seq(descriptor), producerId = requesterId) + val eService = SpecData.catalogItem.copy(descriptors = Seq.empty, producerId = requesterId) (mockCatalogManagementService .getEServiceById(_: UUID)(_: ExecutionContext, _: ReadModelService)) @@ -2419,6 +2418,33 @@ class CatalogProcessSpec extends SpecHelper with AnyWordSpecLike with ScalatestR status shouldEqual StatusCodes.NotFound } } + "fail if EService has descriptors" in { + + val requesterId = UUID.randomUUID() + val descriptorId = UUID.randomUUID() + implicit val context: Seq[(String, String)] = + Seq("bearer" -> bearerToken, USER_ROLES -> "admin", ORGANIZATION_ID_CLAIM -> requesterId.toString) + + val descriptor = SpecData.catalogDescriptor.copy(id = descriptorId) + + val eService = SpecData.catalogItem.copy(descriptors = Seq(descriptor), producerId = requesterId) + + (mockCatalogManagementService + .getEServiceById(_: UUID)(_: ExecutionContext, _: ReadModelService)) + .expects(SpecData.catalogItem.id, *, *) + .once() + .returns(Future.successful(eService)) + + (mockCatalogManagementService + .deleteEService(_: String)(_: Seq[(String, String)])) + .expects(eService.id.toString, *) + .returning(Future.failed(EServiceWithDescriptorsNotDeletable(SpecData.catalogItem.id.toString))) + .once() + + Delete() ~> service.deleteEService(SpecData.catalogItem.id.toString) ~> check { + status shouldEqual StatusCodes.Conflict + } + } "fail if requester is not the Producer" in { implicit val context: Seq[(String, String)] = Seq("bearer" -> bearerToken, USER_ROLES -> "admin", ORGANIZATION_ID_CLAIM -> UUID.randomUUID().toString)