Skip to content

Commit

Permalink
Commonize ktor plugins setup
Browse files Browse the repository at this point in the history
  • Loading branch information
kunyavskiy committed May 12, 2024
1 parent 6ddd7ac commit 1073b5e
Show file tree
Hide file tree
Showing 10 changed files with 66 additions and 160 deletions.
12 changes: 3 additions & 9 deletions src/backend/build.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -42,20 +42,14 @@ tasks {
}

dependencies {
implementation(projects.cds.full)
implementation(projects.backendApi)
implementation(projects.serverShared)
implementation(libs.cli)
implementation(libs.ktor.serialization.kotlinx.json)
implementation(libs.ktor.server.auth)
implementation(libs.ktor.server.autoHeadResponse)
implementation(libs.ktor.server.callLogging)
implementation(libs.ktor.server.contentNegotiation)
implementation(libs.ktor.server.core)
implementation(libs.ktor.server.cors)
implementation(libs.ktor.server.defaultHeaders)
implementation(libs.ktor.server.netty)
implementation(libs.ktor.server.statusPages)
implementation(libs.ktor.server.websockets)
implementation(libs.logback)
implementation(projects.backendApi)
implementation(projects.cds.full)
implementation(projects.serverShared)
}
38 changes: 5 additions & 33 deletions src/backend/src/main/kotlin/org/icpclive/Application.kt
Original file line number Diff line number Diff line change
@@ -1,20 +1,12 @@
package org.icpclive

import org.icpclive.util.completeOrThrow
import io.ktor.http.*
import io.ktor.serialization.kotlinx.json.*
import org.icpclive.util.completeOrThrow
import io.ktor.server.application.*
import io.ktor.server.auth.*
import io.ktor.server.http.content.*
import io.ktor.server.plugins.autohead.*
import io.ktor.server.plugins.callloging.*
import io.ktor.server.plugins.contentnegotiation.*
import io.ktor.server.plugins.cors.routing.*
import io.ktor.server.plugins.defaultheaders.*
import io.ktor.server.plugins.statuspages.*
import io.ktor.server.request.*
import io.ktor.server.routing.*
import io.ktor.server.util.*
import io.ktor.server.websocket.*
import kotlinx.coroutines.CoroutineExceptionHandler
import kotlinx.coroutines.flow.*
Expand All @@ -26,30 +18,18 @@ import org.icpclive.cds.util.*
import org.icpclive.data.Controllers
import org.icpclive.data.DataBus
import org.icpclive.overlay.configureOverlayRouting
import org.icpclive.server.serverResponseJsonSettings
import org.icpclive.server.setupDefaultKtorPlugins
import org.icpclive.service.launchServices
import org.icpclive.util.defaultJsonSettings
import org.slf4j.event.Level
import java.time.Duration
import kotlin.system.exitProcess


fun main(args: Array<String>): Unit = Config.main(args)

private fun Application.setupKtorPlugins() {
install(DefaultHeaders)
install(CallLogging) {
level = Level.INFO
filter { call -> call.request.path().startsWith("/") }
}
install(StatusPages) {
exception<Throwable> { call, ex ->
call.application.environment.log.error("Query ${call.url()} failed with exception", ex)
throw ex
}
}
install(AutoHeadResponse)
install(IgnoreTrailingSlash)
install(ContentNegotiation) { json(defaultJsonSettings()) }
setupDefaultKtorPlugins()
install(ContentNegotiation) { json(serverResponseJsonSettings()) }
install(WebSockets) {
pingPeriod = Duration.ofSeconds(15)
timeout = Duration.ofSeconds(15)
Expand All @@ -76,14 +56,6 @@ private fun Application.setupKtorPlugins() {
}
}
}
install(CORS) {
allowHeader(HttpHeaders.Authorization)
allowHeader(HttpHeaders.ContentType)
allowHeader("*")
allowMethod(HttpMethod.Delete)
allowSameOrigin = true
anyHost()
}
}

@Suppress("unused") // application.yaml references the main function. This annotation prevents the IDE from marking it as unused.
Expand Down
3 changes: 2 additions & 1 deletion src/backend/src/main/kotlin/org/icpclive/util/WebSockets.kt
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ import kotlinx.coroutines.async
import kotlinx.coroutines.flow.Flow
import kotlinx.coroutines.flow.map
import kotlinx.serialization.encodeToString
import org.icpclive.server.serverResponseJsonSettings

suspend fun DefaultWebSocketServerSession.sendFlow(flow: Flow<String>) {
val sender = async {
Expand All @@ -24,6 +25,6 @@ suspend fun DefaultWebSocketServerSession.sendFlow(flow: Flow<String>) {
}

suspend inline fun <reified T> DefaultWebSocketServerSession.sendJsonFlow(flow: Flow<T>) {
val formatter = defaultJsonSettings()
val formatter = serverResponseJsonSettings()
sendFlow(flow.map { formatter.encodeToString(it) })
}
15 changes: 4 additions & 11 deletions src/cds-converter/build.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -18,19 +18,12 @@ tasks.runTask {
}

dependencies {
implementation(projects.cds.full)
implementation(projects.clicsApi)
implementation(projects.serverShared)
implementation(libs.apache.commons.csv)
implementation(libs.cli)
implementation(libs.ktor.serialization.kotlinx.json)
implementation(libs.ktor.server.autoHeadResponse)
implementation(libs.ktor.server.callLogging)
implementation(libs.ktor.server.contentNegotiation)
implementation(libs.ktor.server.core)
implementation(libs.ktor.server.cors)
implementation(libs.ktor.server.defaultHeaders)
implementation(libs.ktor.server.netty)
implementation(libs.ktor.server.statusPages)
implementation(libs.ktor.server.websockets)
implementation(libs.apache.commons.csv)
implementation(projects.cds.full)
implementation(projects.clicsApi)
implementation(projects.serverShared)
}
44 changes: 2 additions & 42 deletions src/cds-converter/src/main/kotlin/Application.kt
Original file line number Diff line number Diff line change
Expand Up @@ -6,28 +6,18 @@ import com.github.ajalt.clikt.core.*
import com.github.ajalt.clikt.output.MordantHelpFormatter
import com.github.ajalt.clikt.parameters.arguments.argument
import com.github.ajalt.clikt.parameters.arguments.multiple
import com.github.ajalt.clikt.parameters.options.*
import io.ktor.http.*
import io.ktor.server.application.*
import io.ktor.server.plugins.autohead.*
import io.ktor.server.plugins.callloging.*
import io.ktor.server.plugins.cors.routing.*
import io.ktor.server.plugins.defaultheaders.*
import io.ktor.server.plugins.statuspages.*
import io.ktor.server.request.*
import io.ktor.server.response.*
import io.ktor.server.routing.*
import io.ktor.server.util.*
import io.ktor.server.websocket.*
import kotlinx.coroutines.CoroutineExceptionHandler
import kotlinx.coroutines.flow.SharingStarted
import kotlinx.coroutines.flow.shareIn
import kotlinx.coroutines.plus
import org.icpclive.export.clics.ClicsExporter
import org.icpclive.export.icpc.csv.IcpcCsvExporter
import org.icpclive.export.pcms.PCMSExporter
import org.slf4j.event.Level
import java.time.Duration
import org.icpclive.server.setupDefaultKtorPlugins
import kotlin.system.exitProcess


Expand Down Expand Up @@ -56,39 +46,9 @@ fun main(args: Array<String>): Unit = MainCommand.subcommands(
).main(args)


private fun Application.setupKtorPlugins() {
install(DefaultHeaders)
install(CallLogging) {
level = Level.INFO
filter { call -> call.request.path().startsWith("/") }
}
install(StatusPages) {
exception<Throwable> { call, ex ->
call.application.environment.log.error("Query ${call.url()} failed with exception", ex)
throw ex
}
}
install(AutoHeadResponse)
install(IgnoreTrailingSlash)
install(WebSockets) {
pingPeriod = Duration.ofSeconds(15)
timeout = Duration.ofSeconds(15)
maxFrameSize = Long.MAX_VALUE
masking = false
}
install(CORS) {
allowHeader(HttpHeaders.Authorization)
allowHeader(HttpHeaders.ContentType)
allowHeader("*")
allowMethod(HttpMethod.Delete)
allowSameOrigin = true
anyHost()
}
}

@Suppress("unused") // application.yaml references the main function. This annotation prevents the IDE from marking it as unused.
fun Application.module() {
setupKtorPlugins()
setupDefaultKtorPlugins()

val handler = CoroutineExceptionHandler { coroutineContext, throwable ->
environment.log.error("Uncaught exception in coroutine context $coroutineContext", throwable)
Expand Down
13 changes: 3 additions & 10 deletions src/oracle-tools/build.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -31,19 +31,12 @@ tasks {
}

dependencies {
implementation(projects.cds.full)
implementation(projects.backendApi)
implementation(projects.serverShared)
implementation(libs.cli)
implementation(libs.ktor.serialization.kotlinx.json)
implementation(libs.ktor.server.auth)
implementation(libs.ktor.server.autoHeadResponse)
implementation(libs.ktor.server.callLogging)
implementation(libs.ktor.server.contentNegotiation)
implementation(libs.ktor.server.core)
implementation(libs.ktor.server.cors)
implementation(libs.ktor.server.defaultHeaders)
implementation(libs.ktor.server.netty)
implementation(libs.ktor.server.statusPages)
implementation(libs.ktor.server.websockets)
implementation(projects.backendApi)
implementation(projects.cds.full)
implementation(projects.serverShared)
}
Original file line number Diff line number Diff line change
@@ -1,66 +1,19 @@
package org.icpclive.oracle

import io.ktor.http.*
import io.ktor.serialization.kotlinx.json.*
import io.ktor.server.application.*
import io.ktor.server.http.content.*
import io.ktor.server.plugins.autohead.*
import io.ktor.server.plugins.callloging.*
import io.ktor.server.plugins.contentnegotiation.*
import io.ktor.server.plugins.cors.routing.*
import io.ktor.server.plugins.defaultheaders.*
import io.ktor.server.plugins.statuspages.*
import io.ktor.server.request.*
import io.ktor.server.response.*
import io.ktor.server.routing.*
import io.ktor.server.util.*
import io.ktor.server.websocket.*
import kotlinx.serialization.json.Json
import org.slf4j.event.Level
import java.time.Duration
import org.icpclive.server.serverResponseJsonSettings
import org.icpclive.server.setupDefaultKtorPlugins

fun main(args: Array<String>): Unit = Config.main(args)


private fun Application.setupKtorPlugins() {
install(DefaultHeaders)
install(CallLogging) {
level = Level.INFO
filter { call -> call.request.path().startsWith("/") }
}
install(StatusPages) {
exception<Throwable> { call, ex ->
call.application.environment.log.error("Query ${call.url()} failed with exception", ex)
throw ex
}
}
install(AutoHeadResponse)
install(IgnoreTrailingSlash)
install(ContentNegotiation) {
json(Json {
encodeDefaults = true
isLenient = true
allowSpecialFloatingPointValues = true
allowStructuredMapKeys = true
prettyPrint = false
useArrayPolymorphism = false
explicitNulls = false
})
}
install(WebSockets) {
pingPeriod = Duration.ofSeconds(15)
timeout = Duration.ofSeconds(15)
maxFrameSize = Long.MAX_VALUE
masking = false
}
install(CORS) {
allowHeader(HttpHeaders.Authorization)
allowHeader(HttpHeaders.ContentType)
allowHeader("*")
allowMethod(HttpMethod.Delete)
allowSameOrigin = true
anyHost()
}
setupDefaultKtorPlugins()
install(ContentNegotiation) { json(serverResponseJsonSettings()) }
}

@Suppress("unused") // application.yaml references the main function. This annotation prevents the IDE from marking it as unused.
Expand Down
7 changes: 6 additions & 1 deletion src/server-shared/build.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,13 @@ plugins {

dependencies {
api(libs.cli)
implementation(libs.ktor.serialization.kotlinx.json)
implementation(libs.ktor.server.autoHeadResponse)
implementation(libs.ktor.server.callLogging)
implementation(libs.ktor.server.core)
implementation(libs.ktor.server.cors)
implementation(libs.ktor.server.defaultHeaders)
implementation(libs.ktor.server.netty)
implementation(libs.ktor.serialization.kotlinx.json)
implementation(libs.ktor.server.statusPages)
implementation(libs.logback)
}
Original file line number Diff line number Diff line change
@@ -1,10 +1,10 @@
package org.icpclive.util
package org.icpclive.server

import kotlinx.serialization.ExperimentalSerializationApi
import kotlinx.serialization.json.Json

@OptIn(ExperimentalSerializationApi::class)
fun defaultJsonSettings(): Json = Json {
fun serverResponseJsonSettings(): Json = Json {
encodeDefaults = true
isLenient = true
allowSpecialFloatingPointValues = true
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
package org.icpclive.server

import io.ktor.server.application.*
import io.ktor.server.plugins.autohead.*
import io.ktor.server.plugins.callloging.*
import io.ktor.server.plugins.cors.routing.*
import io.ktor.server.plugins.defaultheaders.*
import io.ktor.server.plugins.statuspages.*
import io.ktor.server.request.*
import io.ktor.server.routing.*
import io.ktor.server.util.*

fun Application.setupDefaultKtorPlugins() {
install(DefaultHeaders)
install(CallLogging) {
level = org.slf4j.event.Level.INFO
filter { call -> call.request.path().startsWith("/") }
}
install(StatusPages) {
exception<Throwable> { call, ex ->
call.application.environment.log.error("Query ${call.url()} failed with exception", ex)
throw ex
}
}
install(AutoHeadResponse)
install(IgnoreTrailingSlash)
install(CORS) {
allowHeader(io.ktor.http.HttpHeaders.Authorization)
allowHeader(io.ktor.http.HttpHeaders.ContentType)
allowHeader("*")
allowMethod(io.ktor.http.HttpMethod.Delete)
allowSameOrigin = true
anyHost()
}
}

0 comments on commit 1073b5e

Please sign in to comment.