diff --git a/server/src/main/scala/za/co/absa/atum/server/api/http/Routes.scala b/server/src/main/scala/za/co/absa/atum/server/api/http/Routes.scala index 0069a7b0..d1ceba6a 100644 --- a/server/src/main/scala/za/co/absa/atum/server/api/http/Routes.scala +++ b/server/src/main/scala/za/co/absa/atum/server/api/http/Routes.scala @@ -25,10 +25,10 @@ import sttp.tapir.server.interceptor.metrics.MetricsRequestInterceptor import sttp.tapir.swagger.bundle.SwaggerInterpreter import sttp.tapir.ztapir._ import za.co.absa.atum.model.dto.{AdditionalDataDTO, AdditionalDataPatchDTO, CheckpointV2DTO, PartitioningWithIdDTO} +import za.co.absa.atum.model.envelopes.{ErrorResponse, StatusResponse} import za.co.absa.atum.server.api.controller.{CheckpointController, FlowController, PartitioningController} import za.co.absa.atum.server.config.{HttpMonitoringConfig, JvmMonitoringConfig} -import za.co.absa.atum.server.model.ErrorResponse -import za.co.absa.atum.server.model.SuccessResponse._ +import za.co.absa.atum.model.envelopes.SuccessResponse._ import zio._ import zio.interop.catz._ import zio.metrics.connectors.prometheus.PrometheusPublisher @@ -57,7 +57,7 @@ trait Routes extends Endpoints with ServerOptions { createServerEndpoint(postPartitioningEndpointV2, PartitioningController.postPartitioning), createServerEndpoint( getPartitioningAdditionalDataEndpointV2, - PartitioningController.getPartitioningAdditionalDataV2 + PartitioningController.getPartitioningAdditionalData ), createServerEndpoint[ (Long, AdditionalDataPatchDTO), @@ -90,6 +90,14 @@ trait Routes extends Endpoints with ServerOptions { CheckpointController.getPartitioningCheckpoints(partitioningId, limit, offset, checkpointName) } ), + createServerEndpoint[ + (Long, Option[Int], Option[Long], Option[String]), + ErrorResponse, + PaginatedResponse[CheckpointV2DTO] + ](getFlowCheckpointsEndpointV2, { + case (flowId: Long, limit: Option[Int], offset: Option[Long], checkpointName: Option[String]) => + FlowController.getFlowCheckpoints(flowId, limit, offset, checkpointName) + }), createServerEndpoint(getPartitioningByIdEndpointV2, PartitioningController.getPartitioningByIdV2), createServerEndpoint(getPartitioningMeasuresEndpointV2, PartitioningController.getPartitioningMeasuresV2), createServerEndpoint(getPartitioningMainFlowEndpointV2, PartitioningController.getPartitioningMainFlow), @@ -113,7 +121,7 @@ trait Routes extends Endpoints with ServerOptions { PartitioningController.getAncestors(partitioningId, limit, offset) } ), - createServerEndpoint(healthEndpoint, (_: Unit) => ZIO.unit) + createServerEndpoint(healthEndpoint, (_: Unit) => ZIO.succeed(StatusResponse.up)) ) ZHttp4sServerInterpreter[HttpEnv.Env](http4sServerOptions(metricsInterceptorOption)).from(endpoints).toRoutes } @@ -127,14 +135,16 @@ trait Routes extends Endpoints with ServerOptions { // postCheckpointEndpointV2, createPartitioningEndpointV1, // postPartitioningEndpointV2, - // patchPartitioningAdditionalDataEndpointV2, + patchPartitioningAdditionalDataEndpointV2, // getPartitioningCheckpointsEndpointV2, // getPartitioningCheckpointEndpointV2, // getPartitioningMeasuresEndpointV2, - // getPartitioningEndpointV2, + getPartitioningEndpointV2, // getPartitioningMeasuresEndpointV2, // getFlowPartitioningsEndpointV2, - // getPartitioningMainFlowEndpointV2 + // getPartitioningMainFlowEndpointV2, + // getFlowCheckpointsEndpointV2, + healthEndpoint ) ZHttp4sServerInterpreter[HttpEnv.Env](http4sServerOptions(None)) .from(SwaggerInterpreter().fromEndpoints[HttpEnv.F](endpoints, "Atum API", "1.0")) @@ -149,16 +159,16 @@ trait Routes extends Endpoints with ServerOptions { } private def createServerEndpoint[I, E, O]( - endpoint: PublicEndpoint[I, E, O, Any], - logic: I => ZIO[HttpEnv.Env, E, O] - ): ZServerEndpoint[HttpEnv.Env, Any] = { + endpoint: PublicEndpoint[I, E, O, Any], + logic: I => ZIO[HttpEnv.Env, E, O] + ): ZServerEndpoint[HttpEnv.Env, Any] = { endpoint.zServerLogic(logic).widen[HttpEnv.Env] } protected def allRoutes( - httpMonitoringConfig: HttpMonitoringConfig, - jvmMonitoringConfig: JvmMonitoringConfig - ): HttpRoutes[HttpEnv.F] = { + httpMonitoringConfig: HttpMonitoringConfig, + jvmMonitoringConfig: JvmMonitoringConfig + ): HttpRoutes[HttpEnv.F] = { createAllServerRoutes(httpMonitoringConfig) <+> createSwaggerRoutes <+> (if (httpMonitoringConfig.enabled) http4sMetricsRoutes else HttpRoutes.empty[HttpEnv.F]) <+> diff --git a/server/src/test/scala/za/co/absa/atum/server/api/TestData.scala b/server/src/test/scala/za/co/absa/atum/server/api/TestData.scala index 6a7050e9..33f88ce5 100644 --- a/server/src/test/scala/za/co/absa/atum/server/api/TestData.scala +++ b/server/src/test/scala/za/co/absa/atum/server/api/TestData.scala @@ -92,7 +92,7 @@ trait TestData { ) protected val getAncestorsResult1: GetAncestorsResult = GetAncestorsResult( - ancestor_id = 1111L, + ancestor_id = 1L, partitioningJson = partitioningAsJson, author = "author", hasMore = false @@ -105,13 +105,6 @@ trait TestData { hasMore = true ) - protected val getAncestorsResult3: GetAncestorsResult = GetAncestorsResult( - ancestor_id = 3333L, - partitioningJson = partitioningAsJson, - author = "author", - hasMore = false - ) - // Partitioning with ID DTO protected val partitioningWithIdDTO1: PartitioningWithIdDTO = PartitioningWithIdDTO( id = partitioningFromDB1.id, diff --git a/server/src/test/scala/za/co/absa/atum/server/api/http/GetAncestorsEndpointV2UnitTests.scala b/server/src/test/scala/za/co/absa/atum/server/api/http/GetAncestorsEndpointV2UnitTests.scala index 714ac4ac..d467befd 100644 --- a/server/src/test/scala/za/co/absa/atum/server/api/http/GetAncestorsEndpointV2UnitTests.scala +++ b/server/src/test/scala/za/co/absa/atum/server/api/http/GetAncestorsEndpointV2UnitTests.scala @@ -24,10 +24,10 @@ import sttp.model.StatusCode import sttp.tapir.server.stub.TapirStubInterpreter import sttp.tapir.ztapir.{RIOMonadError, RichZEndpoint} import za.co.absa.atum.model.dto.PartitioningWithIdDTO +import za.co.absa.atum.model.envelopes.{InternalServerErrorResponse, NotFoundErrorResponse, Pagination} import za.co.absa.atum.server.api.TestData import za.co.absa.atum.server.api.controller.PartitioningController -import za.co.absa.atum.server.model.{InternalServerErrorResponse, NotFoundErrorResponse, Pagination} -import za.co.absa.atum.server.model.SuccessResponse.PaginatedResponse +import za.co.absa.atum.model.envelopes.SuccessResponse.PaginatedResponse import zio.test.Assertion.equalTo import zio.test.{Spec, TestEnvironment, ZIOSpecDefault, assertZIO} import zio.{Scope, ZIO, ZLayer} diff --git a/server/src/test/scala/za/co/absa/atum/server/api/repository/PartitioningRepositoryUnitTests.scala b/server/src/test/scala/za/co/absa/atum/server/api/repository/PartitioningRepositoryUnitTests.scala index b3a0b43e..104fdc46 100644 --- a/server/src/test/scala/za/co/absa/atum/server/api/repository/PartitioningRepositoryUnitTests.scala +++ b/server/src/test/scala/za/co/absa/atum/server/api/repository/PartitioningRepositoryUnitTests.scala @@ -22,7 +22,7 @@ import za.co.absa.atum.server.api.TestData import za.co.absa.atum.server.api.database.flows.functions.GetFlowPartitionings import za.co.absa.atum.server.api.database.flows.functions.GetFlowPartitionings.GetFlowPartitioningsArgs import za.co.absa.atum.server.api.database.runs.functions.GetAncestors -import za.co.absa.atum.server.api.database.runs.functions.GetAncestors.{GetAncestorsArgs, GetAncestorsResult} +import za.co.absa.atum.server.api.database.runs.functions.GetAncestors.GetAncestorsArgs import za.co.absa.atum.server.api.database.runs.functions.CreateOrUpdateAdditionalData.CreateOrUpdateAdditionalDataArgs import za.co.absa.atum.server.api.database.runs.functions._ import za.co.absa.atum.server.api.exception.DatabaseError @@ -34,7 +34,7 @@ import zio._ import zio.interop.catz.asyncInstance import zio.test.Assertion.failsWithA import zio.test._ -import za.co.absa.atum.server.model.{AdditionalDataFromDB, AdditionalDataItemFromDB, PartitioningForDB} +import za.co.absa.atum.server.model.{AdditionalDataItemFromDB, PartitioningForDB} object PartitioningRepositoryUnitTests extends ZIOSpecDefault with TestData { @@ -96,19 +96,10 @@ object PartitioningRepositoryUnitTests extends ZIOSpecDefault with TestData { private val getPartitioningMeasuresMockLayer = ZLayer.succeed(getPartitioningMeasuresMock) - // Get Partitioning Additional Data Mocks - private val getPartitioningAdditionalDataMock = mock(classOf[GetPartitioningAdditionalData]) - - when(getPartitioningAdditionalDataMock.apply(partitioningDTO1)) - .thenReturn(ZIO.right(Seq(Row(FunctionStatus(0, "success"), AdditionalDataFromDB(Some("key"), Some("value")))))) - when(getPartitioningAdditionalDataMock.apply(partitioningDTO2)).thenReturn(ZIO.fail(new Exception("boom!"))) - - private val getPartitioningAdditionalDataMockLayer = ZLayer.succeed(getPartitioningAdditionalDataMock) - // Get Partitioning By Id Mocks private val getPartitioningByIdByIdMock = mock(classOf[GetPartitioningById]) - when(getPartitioningByIdByIdMock.apply(1111L)) + when(getPartitioningByIdByIdMock.apply(1L)) .thenReturn(ZIO.right(Row(FunctionStatus(11, "OK"), Some(partitioningFromDB1)))) when(getPartitioningByIdByIdMock.apply(9999L)) .thenReturn(ZIO.fail(DataNotFoundException(FunctionStatus(41, "Partitioning not found")))) @@ -117,30 +108,18 @@ object PartitioningRepositoryUnitTests extends ZIOSpecDefault with TestData { private val getPartitioningByIdByIdMockLayer = ZLayer.succeed(getPartitioningByIdByIdMock) - // Get Ancestors By Id Mocks - private val getAncestorsMock = mock(classOf[GetAncestors]) - - when(getAncestorsMock.apply(GetAncestorsArgs(2222L, Some(1), Some(1L))) - ).thenReturn(ZIO.right(Seq(Row(FunctionStatus(11, "OK"), Some(getAncestorsResult1))))) - when(getAncestorsMock.apply(GetAncestorsArgs(9999L, Some(1), Some(1L)))) - .thenReturn(ZIO.left(DataNotFoundException(FunctionStatus(41, "Child Partitioning not found")))) - when(getAncestorsMock.apply(GetAncestorsArgs(8888L, Some(1), Some(1L))) - ).thenReturn(ZIO.fail(new Exception("boom!"))) - - private val getAncestorsMockLayer = ZLayer.succeed(getAncestorsMock) - - // GetPartitioningAdditionalDataV2 - private val getPartitioningAdditionalDataV2Mock = mock(classOf[GetPartitioningAdditionalDataV2]) + // GetPartitioningAdditionalData + private val getPartitioningAdditionalDataMock = mock(classOf[GetPartitioningAdditionalData]) - when(getPartitioningAdditionalDataV2Mock.apply(1L)).thenReturn( + when(getPartitioningAdditionalDataMock.apply(1L)).thenReturn( ZIO.right(Seq(Row(FunctionStatus(0, "success"), Some(AdditionalDataItemFromDB("key", Some("value"), "author"))))) ) - when(getPartitioningAdditionalDataV2Mock.apply(2L)).thenReturn(ZIO.fail(new Exception("boom!"))) - when(getPartitioningAdditionalDataV2Mock.apply(3L)).thenReturn( + when(getPartitioningAdditionalDataMock.apply(2L)).thenReturn(ZIO.fail(new Exception("boom!"))) + when(getPartitioningAdditionalDataMock.apply(3L)).thenReturn( ZIO.left(DataNotFoundException(FunctionStatus(41, "not found"))) ) - private val getPartitioningAdditionalDataV2MockLayer = ZLayer.succeed(getPartitioningAdditionalDataV2Mock) + private val getPartitioningAdditionalDataMockLayer = ZLayer.succeed(getPartitioningAdditionalDataMock) // GetPartitioningMeasuresById private val getPartitioningMeasuresV2Mock = mock(classOf[GetPartitioningMeasuresById]) @@ -170,16 +149,30 @@ object PartitioningRepositoryUnitTests extends ZIOSpecDefault with TestData { private val getFlowPartitioningsMock = mock(classOf[GetFlowPartitionings]) when(getFlowPartitioningsMock.apply(GetFlowPartitioningsArgs(1L, Some(10), Some(0))) - ).thenReturn(ZIO.right(Seq(Row(FunctionStatus(11, "OK"), Some(getFlowPartitioningsResult1))))) + ).thenReturn(ZIO.right(Seq(Row(FunctionStatus(11, "OK"), Some(getFlowPartitioningsResult1))))) when(getFlowPartitioningsMock.apply(GetFlowPartitioningsArgs(2L, Some(10), Some(0))) ).thenReturn(ZIO.right(Seq(Row(FunctionStatus(11, "OK"), Some(getFlowPartitioningsResult2))))) when(getFlowPartitioningsMock.apply(GetFlowPartitioningsArgs(0L, None, None))) .thenReturn(ZIO.left(DataNotFoundException(FunctionStatus(41, "Flow not found")))) when(getFlowPartitioningsMock.apply(GetFlowPartitioningsArgs(3L, Some(10), Some(0))) - ).thenReturn(ZIO.fail(new Exception("boom!"))) + ).thenReturn(ZIO.fail(new Exception("boom!"))) private val getFlowPartitioningsMockLayer = ZLayer.succeed(getFlowPartitioningsMock) + // Get Ancestors By Id Mocks + private val getAncestorsMock = mock(classOf[GetAncestors]) + + when(getAncestorsMock.apply(GetAncestorsArgs(1L, Some(10), Some(0))) + ).thenReturn(ZIO.right(Seq(Row(FunctionStatus(11, "OK"), Some(getAncestorsResult1))))) + when(getAncestorsMock.apply(GetAncestorsArgs(1111L, Some(10), Some(0))) + ).thenReturn(ZIO.right(Seq(Row(FunctionStatus(11, "OK"), Some(getAncestorsResult2))))) + when(getAncestorsMock.apply(GetAncestorsArgs(9999L, Some(10), Some(0))) + ).thenReturn(ZIO.left(DataNotFoundException(FunctionStatus(41, "Child Partitioning not found")))) + when(getAncestorsMock.apply(GetAncestorsArgs(8888L, Some(10), Some(0))) + ).thenReturn(ZIO.fail(new Exception("boom!"))) + + private val getAncestorsMockLayer = ZLayer.succeed(getAncestorsMock) + // Create Partitioning Mocks private val getPartitioningMainFlowMock = mock(classOf[GetPartitioningMainFlow]) @@ -278,32 +271,20 @@ object PartitioningRepositoryUnitTests extends ZIOSpecDefault with TestData { } ), suite("GetPartitioningAdditionalDataSuite")( - test("Returns expected Right with Map") { - for { - result <- PartitioningRepository.getPartitioningAdditionalData(partitioningDTO1) - } yield assertTrue(result.get("key").contains(Some("value")) && result.size == 1) - }, - test("Returns expected Left with DatabaseError") { - assertZIO(PartitioningRepository.getPartitioningAdditionalData(partitioningDTO2).exit)( - failsWithA[DatabaseError] - ) - } - ), - suite("GetPartitioningAdditionalDataV2Suite")( test("Returns expected AdditionalDataDTO instance") { for { - result <- PartitioningRepository.getPartitioningAdditionalDataV2(1L) + result <- PartitioningRepository.getPartitioningAdditionalData(1L) } yield assertTrue( result == AdditionalDataDTO(Map.from(Seq("key" -> Some(AdditionalDataItemDTO(Some("value"), "author"))))) ) }, test("Returns expected DatabaseError") { - assertZIO(PartitioningRepository.getPartitioningAdditionalDataV2(2L).exit)( + assertZIO(PartitioningRepository.getPartitioningAdditionalData(2L).exit)( failsWithA[GeneralDatabaseError] ) }, test("Returns expected NotFoundDatabaseError") { - assertZIO(PartitioningRepository.getPartitioningAdditionalDataV2(3L).exit)( + assertZIO(PartitioningRepository.getPartitioningAdditionalData(3L).exit)( failsWithA[NotFoundDatabaseError] ) } @@ -311,7 +292,7 @@ object PartitioningRepositoryUnitTests extends ZIOSpecDefault with TestData { suite("GetPartitioningByIdSuite")( test("GetPartitioningById - Returns expected PartitioningWithIdDTO") { for { - result <- PartitioningRepository.getPartitioningById(1111L) + result <- PartitioningRepository.getPartitioningById(1L) } yield assertTrue(result == partitioningWithIdDTO1) }, test("GetPartitioningById - Returns expected DataNotFoundException") { @@ -329,23 +310,6 @@ object PartitioningRepositoryUnitTests extends ZIOSpecDefault with TestData { ) } ), - suite("GetAncestorsSuite")( - test("Returns expected ResultNoMore[PartitioningWithIdDTO]") { - for { - result <- PartitioningRepository.getAncestors(2222L, Some(1), Some(1L)) - } yield assertTrue(result == ResultNoMore(Seq(partitioningWithIdDTO1))) - }, - test("Returns expected NotFoundDatabaseError") { - assertZIO(PartitioningRepository.getAncestors(9999L, Some(1), Some(1L)).exit)( - failsWithA[NotFoundDatabaseError] - ) - }, - test("Returns expected GeneralDatabaseError") { - assertZIO(PartitioningRepository.getAncestors(8888L, Some(1), Some(1L)).exit)( - failsWithA[GeneralDatabaseError] - ) - } - ), suite("GetPartitioningMeasuresByIdSuite")( test("Returns expected Seq") { for { @@ -399,7 +363,7 @@ object PartitioningRepositoryUnitTests extends ZIOSpecDefault with TestData { test("Returns expected ResultHasMore[PartitioningWithIdDTO]") { for { result <- PartitioningRepository.getFlowPartitionings(2L, Some(10), Some(0)) - } yield assertTrue(result == ResultHasMore(Seq(partitioningWithIdDTO1))) + } yield assertTrue(result == ResultHasMore(Seq(partitioningWithIdDTO2))) }, test("Returns expected NotFoundDatabaseError") { assertZIO(PartitioningRepository.getFlowPartitionings(0L, None, None).exit)( @@ -412,6 +376,28 @@ object PartitioningRepositoryUnitTests extends ZIOSpecDefault with TestData { ) } ), + suite("GetAncestorsSuite")( + test("Returns expected ResultNoMore[PartitioningWithIdDTO]") { + for { + result <- PartitioningRepository.getAncestors(1L, Some(10), Some(0)) + } yield assertTrue(result == ResultNoMore(Seq(partitioningWithIdDTO1))) + }, + test("Returns expected ResultHasMore[PartitioningWithIdDTO]") { + for { + result <- PartitioningRepository.getAncestors(1111L, Some(10), Some(0)) + } yield assertTrue(result == ResultHasMore(Seq(partitioningWithIdDTO2))) + }, + test("Returns expected NotFoundDatabaseError") { + assertZIO(PartitioningRepository.getAncestors(9999L, Some(10), Some(0)).exit)( + failsWithA[NotFoundDatabaseError] + ) + }, + test("Returns expected GeneralDatabaseError") { + assertZIO(PartitioningRepository.getAncestors(8888L, Some(10), Some(0)).exit)( + failsWithA[GeneralDatabaseError] + ) + } + ), suite("GetPartitioningSuite")( test("GetPartitioning - Returns expected PartitioningWithIdDTO") { for { @@ -435,14 +421,13 @@ object PartitioningRepositoryUnitTests extends ZIOSpecDefault with TestData { createPartitioningIfNotExistsMockLayer, createPartitioningMockLayer, getPartitioningMeasuresMockLayer, - getPartitioningAdditionalDataMockLayer, createOrUpdateAdditionalDataMockLayer, getPartitioningByIdByIdMockLayer, - getAncestorsMockLayer, - getPartitioningAdditionalDataV2MockLayer, + getPartitioningAdditionalDataMockLayer, getPartitioningMockLayer, getPartitioningMeasuresV2MockLayer, getFlowPartitioningsMockLayer, + getAncestorsMockLayer, getPartitioningMainFlowMockLayer )