Skip to content

Commit

Permalink
eecg
Browse files Browse the repository at this point in the history
  • Loading branch information
jnatten committed Aug 30, 2023
1 parent 9a244b3 commit e36e6fb
Show file tree
Hide file tree
Showing 14 changed files with 271 additions and 178 deletions.
1 change: 1 addition & 0 deletions .jvmopts
Original file line number Diff line number Diff line change
Expand Up @@ -9,3 +9,4 @@
--add-opens=java.base/java.util=ALL-UNNAMED
--add-opens=java.desktop/java.awt.event=ALL-UNNAMED
--add-opens=java.desktop/java.awt=ALL-UNNAMED
--enable-preview
Original file line number Diff line number Diff line change
Expand Up @@ -106,15 +106,14 @@ class ComponentRegistry(properties: AudioApiProperties)

lazy val clock = new SystemClock

private val services: List[Service] = List(
audioApiController,
seriesController,
private val services: List[SwaggerService] = List(
// audioApiController,
// seriesController,
internController,
healthController
)

private val swaggerDocController = new SwaggerController(services, SwaggerDocControllerConfig.swaggerInfo)

def routes: Kleisli[IO, Request[IO], Response[IO]] = Routes.build(services :+ swaggerDocController)
// private val swaggerDocController = new SwaggerController(services, SwaggerDocControllerConfig.swaggerInfo)

val allServices = services
}
2 changes: 1 addition & 1 deletion audio-api/src/main/scala/no/ndla/audioapi/Main.scala
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,6 @@ object Main extends IOApp {
setPropsFromEnv()
val props = new AudioApiProperties
val mainClass = new MainClass(props)
mainClass.run(args)
IO.never.as(ExitCode.Success)
}
}
83 changes: 74 additions & 9 deletions audio-api/src/main/scala/no/ndla/audioapi/MainClass.scala
Original file line number Diff line number Diff line change
Expand Up @@ -8,18 +8,42 @@

package no.ndla.audioapi

import cats.data.Kleisli
import cats.effect.IO
import io.circe.generic.auto._
import no.ndla.common.Warmup
import no.ndla.network.tapir.NdlaTapirMain
import org.http4s.{Request, Response}
import org.log4s.getLogger
import sttp.tapir.server.ServerEndpoint
import sttp.tapir.server.interceptor.RequestResult
import sttp.tapir.server.jdkhttp.{Id, JdkHttpServer, JdkHttpServerOptions}
import no.ndla.common.DateParser
import no.ndla.common.model.NDLADate
import no.ndla.network.tapir.ErrorBody
import no.ndla.network.tapir.NoNullJsonPrinter._
import org.http4s.circe.CirceEntityCodec.circeEntityEncoder
import org.http4s.headers.`Content-Type`
import org.http4s.server.Router
import org.http4s.{Headers, HttpRoutes, MediaType, Request, Response}
import org.log4s.{Logger, getLogger}
import sttp.model.StatusCode
import sttp.monad.MonadError
import sttp.tapir.generic.auto.schemaForCaseClass
import sttp.tapir.server.http4s.{Http4sServerInterpreter, Http4sServerOptions}
import sttp.tapir.server.interceptor.RequestResult
import sttp.tapir.server.interceptor.decodefailure.DefaultDecodeFailureHandler
import sttp.tapir.server.interceptor.exception.{ExceptionContext, ExceptionHandler}
import sttp.tapir.server.interceptor.reject.{RejectHandler, RejectInterceptor}
import sttp.tapir.server.model.ValuedEndpointOutput
import sttp.tapir.{EndpointInput, statusCode}

class MainClass(override val props: AudioApiProperties) extends NdlaTapirMain {
private val componentRegistry = new ComponentRegistry(props)
override val app: Kleisli[IO, Request[IO], Response[IO]] = componentRegistry.routes
import java.time.LocalDateTime
import java.util.concurrent.Executors

class MainClass(val props: AudioApiProperties) {
val logger = getLogger
private val componentRegistry = new ComponentRegistry(props)
// override val app: Kleisli[IO, Request[IO], Response[IO]] = componentRegistry.routes

private def warmupRequest = (path, params) => Warmup.warmupRequest(props.ApplicationPort, path, params)
override def warmup(): Unit = {
def warmup(): Unit = {
warmupRequest("/audio-api/v1/audio", Map("query" -> "norge", "fallback" -> "true"))
warmupRequest("/audio-api/v1/audio/1", Map("language" -> "nb"))
warmupRequest("/audio-api/v1/series", Map("language" -> "nb"))
Expand All @@ -29,10 +53,51 @@ class MainClass(override val props: AudioApiProperties) extends NdlaTapirMain {
componentRegistry.healthController.setWarmedUp()
}

override def beforeStart(): Unit = {
def beforeStart(): Unit = {
logger.info("Starting DB Migration")
val dBstartMillis = System.currentTimeMillis()
componentRegistry.migrator.migrate(): Unit
logger.info(s"Done DB Migration took ${System.currentTimeMillis() - dBstartMillis} ms")
}

private def hasMethodMismatch(f: RequestResult.Failure): Boolean = f.failures.map(_.failingInput).exists {
case _: EndpointInput.FixedMethod[_] => true
case _ => false
}

case class NdlaRejectHandler[F[_]]() extends RejectHandler[F] {
override def apply(
failure: RequestResult.Failure
)(implicit monad: MonadError[F]): F[Option[ValuedEndpointOutput[_]]] = {
val statusCodeAndBody = if (hasMethodMismatch(failure)) {
ValuedEndpointOutput(jsonBody[ErrorBody], ErrorBody("methodmismatch", "TODO", NDLADate.now(), 405))
.prepend(statusCode, StatusCode.MethodNotAllowed)
} else {
ValuedEndpointOutput(jsonBody[ErrorBody], ErrorBody("notfound", "TODO", NDLADate.now(), 404))
.prepend(statusCode, StatusCode.NotFound)
}
monad.unit(Some(statusCodeAndBody))
}

}

val tapirEndpoints: List[ServerEndpoint[Any, Id]] = componentRegistry.allServices.flatMap(_.builtEndpoints)
val handler = new NdlaRejectHandler[Id]()
val inter = new RejectInterceptor[Id](handler)

val opts = JdkHttpServerOptions.Default
.appendInterceptor(inter)

beforeStart()

private val executor = Executors.newVirtualThreadPerTaskExecutor()

JdkHttpServer()
.options(opts)
.executor(executor)
.addEndpoints(tapirEndpoints)
.port(props.ApplicationPort)
.start()

warmup()
}
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@ import sttp.tapir.generic.auto._
import sttp.tapir.model.CommaSeparated
import sttp.tapir.server.ServerEndpoint
import sttp.tapir._
import sttp.tapir.server.jdkhttp.Id

import java.io.File
import java.nio.file.Files
Expand Down Expand Up @@ -267,16 +268,16 @@ trait AudioController {
readService.getAllTags(query.underlyingOrElse(""), pageSize, pageNo, language).handleErrorsOrOk
}

override val endpoints: List[ServerEndpoint[Any, IO]] = List(
getSearch,
postSearch,
getIds,
getSingle,
deleteAudio,
deleteLanguage,
postNewAudio,
putUpdateAudio,
tagSearch
override val endpoints: List[ServerEndpoint[Any, Id]] = List(
// getSearch,
// postSearch,
// getIds,
// getSingle,
// deleteAudio,
// deleteLanguage,
// postNewAudio,
// putUpdateAudio,
// tagSearch
)

def getBytesAndDeleteFile(file: Part[File]): Part[Array[Byte]] = {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -31,20 +31,20 @@ trait HealthController {

private def getReturnCode(imageResponse: Response[String]) = {
imageResponse.code.code match {
case 200 => Ok()
case _ => InternalServerError()
case 200 => Right("Healthy")
case _ => Left("Internal server error")
}
}

override def checkHealth(): IO[http4s.Response[IO]] = {
override def checkHealth(): Either[String, String] = {
audioRepository
.getRandomAudio()
.map(audio => {
val id = audio.id.get
val previewUrl = s"http://$localhost:$localport${props.AudioControllerPath}$id"
getReturnCode(getApiResponse(previewUrl))
})
.getOrElse(Ok())
.getOrElse(Right("Healthy"))
}
}

Expand Down
Loading

0 comments on commit e36e6fb

Please sign in to comment.