All Downloads are FREE. Search and download functionalities are using the official Maven repository.

jvmMain.kr.jadekim.jext.ktor.BaseKtorServer.kt Maven / Gradle / Ivy

The newest version!
package kr.jadekim.jext.ktor

import com.google.gson.Gson
import io.ktor.server.application.*
import io.ktor.server.config.*
import io.ktor.server.engine.*
import io.ktor.server.routing.*
import kr.jadekim.jext.ktor.module.*
import kr.jadekim.server.http.BaseHttpServer
import org.slf4j.LoggerFactory
import kotlin.coroutines.CoroutineContext
import kotlin.coroutines.EmptyCoroutineContext
import kotlin.time.Duration
import kotlin.time.DurationUnit
import kotlin.time.toDuration

abstract class BaseKtorServer(
    private val engine: ApplicationEngineFactory,
    serverName: String? = null,
    serviceHost: String = "0.0.0.0",
    servicePort: Int = 80,
    val isDevelopmentMode: Boolean = false,
    val rootPath: String = "",
    private val parentCoroutineContext: CoroutineContext = EmptyCoroutineContext,
) : BaseHttpServer(serverName, serviceHost, servicePort) {

    var blockingStart = true
    var stopGracePeriod = 15.toDuration(DurationUnit.SECONDS)

    private val configuration: ApplicationConfig = MapApplicationConfig()

    private var ktorServer: EmbeddedServer? = null

    abstract fun Routing.configureRouting()

    override fun onStart() {
        ktorServer = createKtorServer()
        ktorServer?.start(wait = blockingStart)
    }

    override fun onStop(timeout: Duration) {
        ktorServer?.stop(stopGracePeriod.inWholeMilliseconds, timeout.inWholeMilliseconds)
    }

    protected open fun createModules(): List> = listOf(
        DefaultFeatureModule(),
        ContentNegotiationModule { gson(Gson()) },
        LogPluginsModule(),
        ErrorHandlerModule(),
    )

    protected open fun createKtorServer(): EmbeddedServer {
        return embeddedServer(engine, createServerConfig(createApplicationEnvironment())) { configureEngine() }
    }

    protected open fun createApplicationEnvironment(): ApplicationEnvironment = applicationEnvironment {
        log = LoggerFactory.getLogger("ktor.application")
        config = configuration
    }

    protected open fun createServerConfig(
        environment: ApplicationEnvironment,
    ): ServerConfig = serverConfig(environment) {
        parentCoroutineContext = [email protected]

        rootPath = [email protected]
        developmentMode = isDevelopmentMode

        val ktorModules = createModules()

        ktorModules.mapNotNull { it.createServerModule() }
            .forEach { module(body = it) }

        module(body = createRoutingModule(ktorModules))
    }

    protected open fun TConfiguration.configureEngine() {
        connector {
            host = serviceHost
            port = servicePort
        }
    }

    private fun createRoutingModule(ktorModules: List>) = KtorServerModule {
        routing {
            ktorModules.mapNotNull { it.createRouteScopedModule() }
                .forEach { installModule -> installModule() }

            configureRouting()
        }
    }
}




© 2015 - 2025 Weber Informatics LLC | Privacy Policy