diff --git a/reposilite-backend/reposilite-backend.gradle.kts b/reposilite-backend/reposilite-backend.gradle.kts index 8ab20cfb5..968ffada7 100644 --- a/reposilite-backend/reposilite-backend.gradle.kts +++ b/reposilite-backend/reposilite-backend.gradle.kts @@ -85,13 +85,13 @@ dependencies { implementation("software.amazon.awssdk:bom:$awssdk") implementation("software.amazon.awssdk:s3:$awssdk") - val javalin = "4.0.0.ALPHA3" + val javalin = "4.0.0.RC0" implementation("io.javalin:javalin:$javalin") - val openapi = "1.0.9" - kapt("com.dzikoysk:openapi-annotation-processor:$openapi") - implementation("com.dzikoysk:javalin-openapi-plugin:$openapi") - implementation("com.dzikoysk:javalin-swagger-plugin:$openapi") + val openapi = "1.1.0" + kapt("io.javalin-rfc:openapi-annotation-processor:$openapi") + implementation("io.javalin-rfc:javalin-openapi-plugin:$openapi") + implementation("io.javalin-rfc:javalin-swagger-plugin:$openapi") val jetty = "9.4.42.v20210604" implementation("org.eclipse.jetty:jetty-server:$jetty") diff --git a/reposilite-backend/src/main/kotlin/com/reposilite/ReposiliteWebConfiguration.kt b/reposilite-backend/src/main/kotlin/com/reposilite/ReposiliteWebConfiguration.kt index 709054693..e1d4e1420 100644 --- a/reposilite-backend/src/main/kotlin/com/reposilite/ReposiliteWebConfiguration.kt +++ b/reposilite-backend/src/main/kotlin/com/reposilite/ReposiliteWebConfiguration.kt @@ -94,6 +94,7 @@ object ReposiliteWebConfiguration { fun dispose(reposilite: Reposilite) { ConsoleWebConfiguration.dispose(reposilite.consoleFacade) + StatisticsWebConfiguration.dispose() } } \ No newline at end of file diff --git a/reposilite-backend/src/main/kotlin/com/reposilite/auth/infrastructure/AuthenticationEndpoint.kt b/reposilite-backend/src/main/kotlin/com/reposilite/auth/infrastructure/AuthenticationEndpoint.kt index 141b1d1e0..17a8ab40d 100644 --- a/reposilite-backend/src/main/kotlin/com/reposilite/auth/infrastructure/AuthenticationEndpoint.kt +++ b/reposilite-backend/src/main/kotlin/com/reposilite/auth/infrastructure/AuthenticationEndpoint.kt @@ -15,24 +15,22 @@ */ package com.reposilite.auth.infrastructure -import com.dzikoysk.openapi.annotations.HttpMethod -import com.dzikoysk.openapi.annotations.OpenApi -import com.dzikoysk.openapi.annotations.OpenApiContent -import com.dzikoysk.openapi.annotations.OpenApiParam -import com.dzikoysk.openapi.annotations.OpenApiResponse import com.reposilite.auth.AuthenticationFacade import com.reposilite.auth.api.AuthenticationResponse import com.reposilite.failure.api.ErrorResponse import com.reposilite.web.api.Route import com.reposilite.web.api.RouteMethod.GET import com.reposilite.web.api.Routes - -private const val ROUTE = "/api/auth" +import io.javalin.openapi.HttpMethod +import io.javalin.openapi.OpenApi +import io.javalin.openapi.OpenApiContent +import io.javalin.openapi.OpenApiParam +import io.javalin.openapi.OpenApiResponse internal class AuthenticationEndpoint(private val authenticationFacade: AuthenticationFacade) : Routes { @OpenApi( - path = ROUTE, + path = "/api/auth", methods = [HttpMethod.GET], summary = "Get token details", description = "Returns details about the requested token", @@ -51,7 +49,7 @@ internal class AuthenticationEndpoint(private val authenticationFacade: Authenti ) ] ) - private val authInfo = Route(ROUTE, GET) { + private val authInfo = Route("/api/auth", GET) { authenticationFacade.authenticateByHeader(ctx.headerMap()) .map { AuthenticationResponse(it.alias, it.permissions.map { permission -> permission.toString() }) } .let { ctx.json(it.any) } diff --git a/reposilite-backend/src/main/kotlin/com/reposilite/auth/infrastructure/PostAuthHandler.kt b/reposilite-backend/src/main/kotlin/com/reposilite/auth/infrastructure/PostAuthHandler.kt index 92350a32c..fc17ff62b 100644 --- a/reposilite-backend/src/main/kotlin/com/reposilite/auth/infrastructure/PostAuthHandler.kt +++ b/reposilite-backend/src/main/kotlin/com/reposilite/auth/infrastructure/PostAuthHandler.kt @@ -15,17 +15,17 @@ */ package com.reposilite.auth.infrastructure -import io.javalin.http.HttpCode import com.reposilite.web.api.Route import com.reposilite.web.api.RouteMethod.AFTER import com.reposilite.web.api.Routes +import io.javalin.http.HttpCode private const val WWW_AUTHENTICATE = "www-authenticate" private const val WWW_BASIC_REALM = """Basic realm="Reposilite", charset="UTF-8" """ internal class PostAuthHandler : Routes { - private val realmDescription = Route("/*", AFTER) { + private val realmDescription = Route("/<*>", AFTER) { if (ctx.status() == HttpCode.UNAUTHORIZED.status) { ctx.header(WWW_AUTHENTICATE, WWW_BASIC_REALM) } diff --git a/reposilite-backend/src/main/kotlin/com/reposilite/console/infrastructure/RemoteExecutionEndpoint.kt b/reposilite-backend/src/main/kotlin/com/reposilite/console/infrastructure/RemoteExecutionEndpoint.kt index ab64092e7..7e17f71fe 100644 --- a/reposilite-backend/src/main/kotlin/com/reposilite/console/infrastructure/RemoteExecutionEndpoint.kt +++ b/reposilite-backend/src/main/kotlin/com/reposilite/console/infrastructure/RemoteExecutionEndpoint.kt @@ -15,12 +15,6 @@ */ package com.reposilite.console.infrastructure -import com.dzikoysk.openapi.annotations.HttpMethod -import com.dzikoysk.openapi.annotations.OpenApi -import com.dzikoysk.openapi.annotations.OpenApiContent -import com.dzikoysk.openapi.annotations.OpenApiParam -import com.dzikoysk.openapi.annotations.OpenApiResponse -import io.javalin.http.HttpCode.UNAUTHORIZED import com.reposilite.console.ConsoleFacade import com.reposilite.console.MAX_COMMAND_LENGTH import com.reposilite.console.api.ExecutionResponse @@ -29,13 +23,17 @@ import com.reposilite.failure.api.errorResponse import com.reposilite.web.api.Route import com.reposilite.web.api.RouteMethod.POST import com.reposilite.web.api.Routes - -private const val ROUTE = "/api/execute" +import io.javalin.http.HttpCode.UNAUTHORIZED +import io.javalin.openapi.HttpMethod +import io.javalin.openapi.OpenApi +import io.javalin.openapi.OpenApiContent +import io.javalin.openapi.OpenApiParam +import io.javalin.openapi.OpenApiResponse internal class RemoteExecutionEndpoint(private val consoleFacade: ConsoleFacade) : Routes { @OpenApi( - path = ROUTE, + path = "/api/execute", methods = [HttpMethod.POST], summary = "Remote command execution", description = "Execute command using POST request. The commands are the same as in the console and can be listed using the 'help' command.", @@ -59,7 +57,7 @@ internal class RemoteExecutionEndpoint(private val consoleFacade: ConsoleFacade) ) ] ) - private val executeCommand = Route(ROUTE, POST) { + private val executeCommand = Route("/api/execute", POST) { context.logger.info("REMOTE EXECUTION ${context.uri} from ${context.address}") authenticated { diff --git a/reposilite-backend/src/main/kotlin/com/reposilite/frontend/infrastructure/CustomFrontendHandler.kt b/reposilite-backend/src/main/kotlin/com/reposilite/frontend/infrastructure/CustomFrontendHandler.kt index 167230f0a..124640d1b 100644 --- a/reposilite-backend/src/main/kotlin/com/reposilite/frontend/infrastructure/CustomFrontendHandler.kt +++ b/reposilite-backend/src/main/kotlin/com/reposilite/frontend/infrastructure/CustomFrontendHandler.kt @@ -15,8 +15,8 @@ internal class CustomFrontendHandler(frontendFacade: FrontendFacade, directory: override val routes: Set = Files.list(directory) .map { if (it.isDirectory()) - Route("/${it.getSimpleName()}/*", GET) { - respondWithFile(ctx, it.getSimpleName(), it.resolve(ctx.splat(0) ?: "").inputStream().orNull()) + Route("/${it.getSimpleName()}/", GET) { + respondWithFile(ctx, it.getSimpleName(), it.resolve(ctx.pathParam("path")).inputStream().orNull()) } else Route("/${it.getSimpleName()}", GET) { diff --git a/reposilite-backend/src/main/kotlin/com/reposilite/frontend/infrastructure/ResourcesFrontendHandler.kt b/reposilite-backend/src/main/kotlin/com/reposilite/frontend/infrastructure/ResourcesFrontendHandler.kt index 72f7daee1..3775831c8 100644 --- a/reposilite-backend/src/main/kotlin/com/reposilite/frontend/infrastructure/ResourcesFrontendHandler.kt +++ b/reposilite-backend/src/main/kotlin/com/reposilite/frontend/infrastructure/ResourcesFrontendHandler.kt @@ -30,8 +30,8 @@ internal class ResourcesFrontendHandler(frontendFacade: FrontendFacade) : Fronte respondWithResource(ctx, "index.html") } - private val assetsHandler = Route("/assets/*", GET) { - respondWithResource(ctx, "assets/${wildcard()}") + private val assetsHandler = Route("/assets/", GET) { + respondWithResource(ctx, "assets/${ctx.pathParam("path")}") } private fun respondWithResource(ctx: Context, uri: String) { diff --git a/reposilite-backend/src/main/kotlin/com/reposilite/maven/infrastructure/MavenFileEndpoint.kt b/reposilite-backend/src/main/kotlin/com/reposilite/maven/infrastructure/MavenFileEndpoint.kt index 594ce5f05..3efb65965 100644 --- a/reposilite-backend/src/main/kotlin/com/reposilite/maven/infrastructure/MavenFileEndpoint.kt +++ b/reposilite-backend/src/main/kotlin/com/reposilite/maven/infrastructure/MavenFileEndpoint.kt @@ -1,15 +1,9 @@ package com.reposilite.maven.infrastructure -import com.dzikoysk.openapi.annotations.HttpMethod -import com.dzikoysk.openapi.annotations.OpenApi -import com.dzikoysk.openapi.annotations.OpenApiContent -import com.dzikoysk.openapi.annotations.OpenApiParam -import com.dzikoysk.openapi.annotations.OpenApiResponse import com.reposilite.failure.api.ErrorResponse import com.reposilite.failure.api.errorResponse import com.reposilite.maven.MavenFacade import com.reposilite.maven.api.DeployRequest -import com.reposilite.maven.api.DirectoryInfo import com.reposilite.maven.api.DocumentInfo import com.reposilite.maven.api.FileDetails import com.reposilite.maven.api.LookupRequest @@ -23,30 +17,37 @@ import com.reposilite.web.api.RouteMethod.PUT import com.reposilite.web.api.Routes import com.reposilite.web.resultAttachment import io.javalin.http.HttpCode.NO_CONTENT +import io.javalin.openapi.HttpMethod +import io.javalin.openapi.OpenApi +import io.javalin.openapi.OpenApiContent +import io.javalin.openapi.OpenApiParam +import io.javalin.openapi.OpenApiResponse import panda.std.Result internal class MavenFileEndpoint(private val mavenFacade: MavenFacade) : Routes { @OpenApi( - path = "/:repository-name/*", + path = "/{repository}/*", methods = [HttpMethod.GET], tags = ["Maven"], summary = "Browse the contents of repositories", description = "The route may return various responses to properly handle Maven specification and frontend application using the same path.", - pathParams = [OpenApiParam(name = "*", description = "Artifact path qualifier", required = true, allowEmptyValue = true)], + pathParams = [ + OpenApiParam(name = "*", description = "Artifact path qualifier", required = true, allowEmptyValue = true) + ], responses = [ OpenApiResponse(status = "200", description = "Input stream of requested file", content = [OpenApiContent(type = MULTIPART_FORM_DATA)]), OpenApiResponse(status = "404", description = "Returns 404 (for Maven) with frontend (for user) as a response if requested resource is not located in the current repository") ] ) - val findFile = Route("/:repository-name/*", GET) { + val findFile = Route("/{repository}/", GET) { accessed { - LookupRequest(parameter("repository-name"), wildcard(), this?.accessToken) + LookupRequest(parameter("repository"), parameter("gav"), this?.accessToken) .let { mavenFacade.findFile(it) } .peek { when (it) { is DocumentInfo -> ctx.resultAttachment(it) - is DirectoryInfo -> response = errorResponse(NO_CONTENT, "Requested file is a directory") + else -> response = errorResponse(NO_CONTENT, "Requested file is a directory") } } .onError { response = Result.error(it) } @@ -54,12 +55,14 @@ internal class MavenFileEndpoint(private val mavenFacade: MavenFacade) : Routes } @OpenApi( - path = "/:repository-name/*", + path = "/{repository}/*", methods = [HttpMethod.POST, HttpMethod.PUT], summary = "Deploy artifact to the repository", description = "Deploy supports both, POST and PUT, methods and allows to deploy artifact builds", tags = [ "Maven" ], - pathParams = [ OpenApiParam(name = "*", description = "Artifact path qualifier", required = true) ], + pathParams = [ + OpenApiParam(name = "*", description = "Artifact path qualifier", required = true) + ], responses = [ OpenApiResponse(status = "200", description = "Input stream of requested file", content = [OpenApiContent(type = MULTIPART_FORM_DATA)]), OpenApiResponse(status = "401", description = "Returns 401 for invalid credentials"), @@ -67,32 +70,34 @@ internal class MavenFileEndpoint(private val mavenFacade: MavenFacade) : Routes OpenApiResponse(status = "507", description = "Returns 507 if Reposilite does not have enough disk space to store the uploaded file") ] ) - private val deployFile = Route("/:repository-name/*", POST, PUT) { + private val deployFile = Route("/{repository}/", POST, PUT) { authorized { - response = DeployRequest(parameter("repository-name"), wildcard(), getSessionIdentifier(), context.input()) + response = DeployRequest(parameter("repository"), parameter("gav"), getSessionIdentifier(), context.input()) .let { mavenFacade.deployFile(it) } .onError { context.logger.debug("Cannot deploy artifact due to: ${it.message}") } } } @OpenApi( - path = "/:repository-name/*", + path = "/{repository}/", summary = "Delete the given file from repository", methods = [HttpMethod.DELETE] ) - private val deleteFile = Route("/:repository-name/*", DELETE) { + private val deleteFile = Route("/{repository}/", DELETE) { authorized { - response = mavenFacade.deleteFile(parameter("repository-name"), wildcard()) + response = mavenFacade.deleteFile(parameter("repository"), parameter("gav")) } } @OpenApi( - path = "/api/maven/details/:repository-name/*", + path = "/api/maven/details/{repository}/", methods = [HttpMethod.HEAD, HttpMethod.GET], summary = "Browse the contents of repositories using API", description = "Get details about the requested file as JSON response", tags = ["Maven"], - pathParams = [OpenApiParam(name = "*", description = "Artifact path qualifier", required = true, allowEmptyValue = true)], + pathParams = [ + OpenApiParam(name = "*", description = "Artifact path qualifier", required = true, allowEmptyValue = true) + ], responses = [ OpenApiResponse( status = "200", @@ -110,9 +115,9 @@ internal class MavenFileEndpoint(private val mavenFacade: MavenFacade) : Routes ) ] ) - val findFileDetails = Route("/api/maven/details/:repository-name/*", HEAD, GET) { + val findFileDetails = Route("/api/maven/details/{repository}/", HEAD, GET) { accessed { - response = LookupRequest(parameter("repository-name"), wildcard(), this?.accessToken) + response = LookupRequest(parameter("repository"), parameter("gav"), this?.accessToken) .let { mavenFacade.findFile(it) } } } diff --git a/reposilite-backend/src/main/kotlin/com/reposilite/statistics/application/StatisticsWebConfiguration.kt b/reposilite-backend/src/main/kotlin/com/reposilite/statistics/application/StatisticsWebConfiguration.kt index b12b2d071..955626f1a 100644 --- a/reposilite-backend/src/main/kotlin/com/reposilite/statistics/application/StatisticsWebConfiguration.kt +++ b/reposilite-backend/src/main/kotlin/com/reposilite/statistics/application/StatisticsWebConfiguration.kt @@ -16,25 +16,25 @@ package com.reposilite.statistics.application -import net.dzikoysk.dynamiclogger.Journalist import com.reposilite.console.ConsoleFacade import com.reposilite.statistics.StatisticsFacade import com.reposilite.statistics.StatsCommand import com.reposilite.statistics.infrastructure.SqlStatisticsRepository import com.reposilite.statistics.infrastructure.StatisticsHandler import com.reposilite.web.api.Routes +import net.dzikoysk.dynamiclogger.Journalist import java.util.concurrent.Executors import java.util.concurrent.TimeUnit.MINUTES internal object StatisticsWebConfiguration { + private val scheduler = Executors.newSingleThreadScheduledExecutor() // Maybe use some shared ThreadPool to avoid Thread creation + fun createFacade(journalist: Journalist): StatisticsFacade = StatisticsFacade(journalist, SqlStatisticsRepository()) fun initialize(statisticsFacade: StatisticsFacade, consoleFacade: ConsoleFacade) { - val scheduler = Executors.newSingleThreadScheduledExecutor() // Maybe use some shared ThreadPool to avoid Thread creation scheduler.scheduleWithFixedDelay({ statisticsFacade.saveRecordsBulk() }, 1, 1, MINUTES) - consoleFacade.registerCommand(StatsCommand(statisticsFacade)) } @@ -43,4 +43,8 @@ internal object StatisticsWebConfiguration { StatisticsHandler(statisticsFacade) ) + fun dispose() { + scheduler.shutdown() + } + } \ No newline at end of file diff --git a/reposilite-backend/src/main/kotlin/com/reposilite/statistics/infrastructure/StatisticsHandler.kt b/reposilite-backend/src/main/kotlin/com/reposilite/statistics/infrastructure/StatisticsHandler.kt index 7e4e193e6..abb4d3a2c 100644 --- a/reposilite-backend/src/main/kotlin/com/reposilite/statistics/infrastructure/StatisticsHandler.kt +++ b/reposilite-backend/src/main/kotlin/com/reposilite/statistics/infrastructure/StatisticsHandler.kt @@ -25,7 +25,7 @@ import com.reposilite.web.api.Routes internal class StatisticsHandler(private val statisticsFacade: StatisticsFacade) : Routes { - private val collectRequests = Route("/*", BEFORE) { + private val collectRequests = Route("/<*>", BEFORE) { if (ctx.req.requestURI.length < MAX_IDENTIFIER_LENGTH) { statisticsFacade.increaseRecord(REQUEST, ctx.req.requestURI) } diff --git a/reposilite-backend/src/main/kotlin/com/reposilite/web/ContextDsl.kt b/reposilite-backend/src/main/kotlin/com/reposilite/web/ContextDsl.kt index 17831b561..2aacaca99 100644 --- a/reposilite-backend/src/main/kotlin/com/reposilite/web/ContextDsl.kt +++ b/reposilite-backend/src/main/kotlin/com/reposilite/web/ContextDsl.kt @@ -16,10 +16,10 @@ package com.reposilite.web -import io.javalin.http.Context -import io.javalin.http.HttpCode import com.reposilite.auth.Session import com.reposilite.failure.api.ErrorResponse +import io.javalin.http.Context +import io.javalin.http.HttpCode import panda.std.Result class ContextDsl(val ctx: Context, val context: ReposiliteContext) { @@ -58,14 +58,6 @@ class ContextDsl(val ctx: Context, val context: ReposiliteContext) { } } - /** - * Get first available splat or empty string - */ - fun wildcard(defaultValue: String = ""): String = - ctx.splat(0) - .takeIf { it?.isNotEmpty() ?: false } - ?: defaultValue - fun parameter(name: String): String = ctx.pathParam(name) diff --git a/reposilite-backend/src/main/kotlin/com/reposilite/web/api/Route.kt b/reposilite-backend/src/main/kotlin/com/reposilite/web/api/Route.kt index 324fa3ac9..0723fd4ef 100644 --- a/reposilite-backend/src/main/kotlin/com/reposilite/web/api/Route.kt +++ b/reposilite-backend/src/main/kotlin/com/reposilite/web/api/Route.kt @@ -16,10 +16,13 @@ package com.reposilite.web.api -import io.javalin.http.Handler import com.reposilite.web.ContextDsl import com.reposilite.web.ReposiliteContextFactory import com.reposilite.web.context +import io.javalin.http.Handler +import java.text.Collator +import java.text.RuleBasedCollator +import java.util.Locale enum class RouteMethod { HEAD, @@ -37,6 +40,12 @@ class Route( private val handler: ContextDsl.() -> Unit ) : Comparable { + private companion object { + + private val routesRule = RuleBasedCollator((Collator.getInstance(Locale.US) as RuleBasedCollator).rules.toString() + "& Z < '{' < '<'") + + } + fun createHandler(reposiliteContextFactory: ReposiliteContextFactory): Handler = Handler { context(reposiliteContextFactory, it) { @@ -56,7 +65,8 @@ class Route( val itPart = itPaths[index] val toPart = toPaths[index] - val result = toPart.compareTo(itPart) + + val result = routesRule.compare(itPart, toPart) if (result != 0) { return result @@ -65,7 +75,7 @@ class Route( index++ } - return other.path.compareTo(path) + return routesRule.compare(path, other.path) } } diff --git a/reposilite-backend/src/main/kotlin/com/reposilite/web/infrastructure/JavalinWebServer.kt b/reposilite-backend/src/main/kotlin/com/reposilite/web/infrastructure/JavalinWebServer.kt index e6fdccf7a..192b3f360 100644 --- a/reposilite-backend/src/main/kotlin/com/reposilite/web/infrastructure/JavalinWebServer.kt +++ b/reposilite-backend/src/main/kotlin/com/reposilite/web/infrastructure/JavalinWebServer.kt @@ -1,11 +1,11 @@ package com.reposilite.web.infrastructure -import io.javalin.Javalin import com.reposilite.Reposilite import com.reposilite.ReposiliteWebConfiguration import com.reposilite.config.Configuration import com.reposilite.web.WebServer import com.reposilite.web.alsoIf +import io.javalin.Javalin internal class JavalinWebServer : WebServer { @@ -40,6 +40,6 @@ internal class JavalinWebServer : WebServer { } override fun isAlive(): Boolean = - javalin?.server()?.server()?.isStarted ?: false + javalin?.jettyServer()?.server()?.isStarted ?: false } \ No newline at end of file diff --git a/reposilite-backend/src/main/kotlin/com/reposilite/web/infrastructure/JavalinWebServerConfiguration.kt b/reposilite-backend/src/main/kotlin/com/reposilite/web/infrastructure/JavalinWebServerConfiguration.kt index 23caa1913..6ed5e1ca2 100644 --- a/reposilite-backend/src/main/kotlin/com/reposilite/web/infrastructure/JavalinWebServerConfiguration.kt +++ b/reposilite-backend/src/main/kotlin/com/reposilite/web/infrastructure/JavalinWebServerConfiguration.kt @@ -1,17 +1,7 @@ package com.reposilite.web.infrastructure -import com.dzikoysk.openapi.ktor.OpenApiConfiguration -import com.dzikoysk.openapi.ktor.OpenApiPlugin -import com.dzikoysk.openapi.ktor.swagger.SwaggerConfiguration -import com.dzikoysk.openapi.ktor.swagger.SwaggerPlugin import com.fasterxml.jackson.annotation.JsonInclude.Include import com.fasterxml.jackson.databind.ObjectMapper -import io.javalin.Javalin -import io.javalin.core.JavalinConfig -import io.javalin.plugin.json.JavalinJackson -import org.eclipse.jetty.server.Server -import org.eclipse.jetty.server.ServerConnector -import org.eclipse.jetty.util.ssl.SslContextFactory import com.reposilite.Reposilite import com.reposilite.ReposiliteWebConfiguration import com.reposilite.VERSION @@ -23,6 +13,16 @@ import com.reposilite.web.api.RouteMethod.GET import com.reposilite.web.api.RouteMethod.HEAD import com.reposilite.web.api.RouteMethod.POST import com.reposilite.web.api.RouteMethod.PUT +import io.javalin.Javalin +import io.javalin.core.JavalinConfig +import io.javalin.openapi.plugin.OpenApiConfiguration +import io.javalin.openapi.plugin.OpenApiPlugin +import io.javalin.openapi.plugin.swagger.SwaggerConfiguration +import io.javalin.openapi.plugin.swagger.SwaggerPlugin +import io.javalin.plugin.json.JavalinJackson +import org.eclipse.jetty.server.Server +import org.eclipse.jetty.server.ServerConnector +import org.eclipse.jetty.util.ssl.SslContextFactory internal object JavalinWebServerConfiguration { @@ -30,7 +30,7 @@ internal object JavalinWebServerConfiguration { val server = Server() configureJavalin(config) - configureJsonSerialization() + configureJsonSerialization(config) configureSSL(reposilite, configuration, config, server) configureCors(config) configureOpenApi(configuration, config) @@ -43,10 +43,10 @@ internal object JavalinWebServerConfiguration { config.showJavalinBanner = false } - private fun configureJsonSerialization() { + private fun configureJsonSerialization(config: JavalinConfig) { val objectMapper = ObjectMapper() objectMapper.setSerializationInclusion(Include.NON_NULL) - JavalinJackson.configure(objectMapper) + config.jsonMapper(JavalinJackson(objectMapper)) } private fun configureSSL(reposilite: Reposilite, configuration: Configuration, config: JavalinConfig, server: Server) {