Skip to content

Commit

Permalink
health endpoint (#282)
Browse files Browse the repository at this point in the history
  • Loading branch information
salamonpavel authored Oct 1, 2024
1 parent 7889f62 commit 0b97d6f
Show file tree
Hide file tree
Showing 4 changed files with 98 additions and 5 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ import sttp.tapir.generic.auto.schemaForCaseClass
import sttp.tapir.json.circe.jsonBody
import sttp.tapir.ztapir._
import za.co.absa.atum.model.dto._
import za.co.absa.atum.server.model.ErrorResponse
import za.co.absa.atum.server.model.{ErrorResponse, StatusResponse}
import za.co.absa.atum.server.model.SuccessResponse._
import sttp.tapir.{PublicEndpoint, Validator, endpoint}
import za.co.absa.atum.server.api.http.ApiPaths.{Health, ZioMetrics, _}
Expand Down Expand Up @@ -177,7 +177,7 @@ trait Endpoints extends BaseEndpoints {
endpoint.get.in(ZioMetrics).out(stringBody)
}

protected val healthEndpoint: PublicEndpoint[Unit, Unit, Unit, Any] =
endpoint.get.in(Health)
protected val healthEndpoint: PublicEndpoint[Unit, Unit, StatusResponse, Any] =
endpoint.get.in(Health).out(jsonBody[StatusResponse].example(StatusResponse.up))

}
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@ import sttp.tapir.ztapir._
import za.co.absa.atum.model.dto.{AdditionalDataDTO, AdditionalDataPatchDTO, CheckpointV2DTO, PartitioningWithIdDTO}
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.{ErrorResponse, StatusResponse}
import za.co.absa.atum.server.model.SuccessResponse._
import zio._
import zio.interop.catz._
Expand Down Expand Up @@ -103,7 +103,7 @@ trait Routes extends Endpoints with ServerOptions {
PartitioningController.getFlowPartitionings(flowId, limit, offset)
}
),
createServerEndpoint(healthEndpoint, (_: Unit) => ZIO.unit)
createServerEndpoint(healthEndpoint, (_: Unit) => ZIO.succeed(StatusResponse.up))
)
ZHttp4sServerInterpreter[HttpEnv.Env](http4sServerOptions(metricsInterceptorOption)).from(endpoints).toRoutes
}
Expand All @@ -125,6 +125,7 @@ trait Routes extends Endpoints with ServerOptions {
// getPartitioningMeasuresEndpointV2,
// getFlowPartitioningsEndpointV2,
// getPartitioningMainFlowEndpointV2
healthEndpoint
)
ZHttp4sServerInterpreter[HttpEnv.Env](http4sServerOptions(None))
.from(SwaggerInterpreter().fromEndpoints[HttpEnv.F](endpoints, "Atum API", "1.0"))
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
/*
* Copyright 2021 ABSA Group Limited
*
* 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.
*/

package za.co.absa.atum.server.model

case class StatusResponse(status: String, message: String)

object StatusResponse {

import io.circe.generic.semiauto._

implicit val encoder: io.circe.Encoder[StatusResponse] = deriveEncoder
implicit val decoder: io.circe.Decoder[StatusResponse] = deriveDecoder

def up: StatusResponse = {
StatusResponse(
status = "UP",
message = "Atum server is up and running"
)
}

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,57 @@
/*
* Copyright 2021 ABSA Group Limited
*
* 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.
*/

package za.co.absa.atum.server.api.http

import sttp.client3.circe.asJson
import sttp.client3.testing.SttpBackendStub
import sttp.client3.{UriContext, basicRequest}
import sttp.model.StatusCode
import sttp.tapir.server.stub.TapirStubInterpreter
import sttp.tapir.ztapir.{RIOMonadError, RichZEndpoint}
import za.co.absa.atum.server.model.StatusResponse
import zio.test.Assertion.equalTo
import zio.test.{Spec, TestEnvironment, ZIOSpecDefault, assertZIO}
import zio.{Scope, ZIO}

object HealthEndpointUnitTests extends ZIOSpecDefault with Endpoints {

private val healthServerEndpoint = healthEndpoint.zServerLogic((_: Unit) => ZIO.succeed(StatusResponse.up))

override def spec: Spec[TestEnvironment with Scope, Any] = {
val backendStub = TapirStubInterpreter(SttpBackendStub.apply(new RIOMonadError[Any]))
.whenServerEndpoint(healthServerEndpoint)
.thenRunLogic()
.backend()

suite("HealthEndpointSuite")(
test("Returns expected StatusResponse") {
val request = basicRequest
.get(uri"https://test.com/health")
.response(asJson[StatusResponse])

val response = request.send(backendStub)

val body = response.map(_.body)
val statusCode = response.map(_.code)

assertZIO(body <&> statusCode)(
equalTo(Right(StatusResponse.up), StatusCode.Ok)
)
}
)
}
}

0 comments on commit 0b97d6f

Please sign in to comment.