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

com.hexagonkt.http.server.servlet.ServletServer.kt Maven / Gradle / Ivy

package com.hexagonkt.http.server.servlet

import com.hexagonkt.core.text.AnsiColor.BLUE
import com.hexagonkt.core.text.AnsiEffect.BOLD
import com.hexagonkt.core.text.AnsiColor.CYAN
import com.hexagonkt.core.text.AnsiColor.MAGENTA
import com.hexagonkt.core.text.Ansi.RESET
import com.hexagonkt.core.Jvm
import com.hexagonkt.core.text.prependIndent
import com.hexagonkt.core.require
import com.hexagonkt.core.logging.Logger
import com.hexagonkt.http.server.HttpServer
import com.hexagonkt.http.server.HttpServerSettings
import com.hexagonkt.http.handlers.HttpHandler
import com.hexagonkt.http.handlers.OnHandler
import jakarta.servlet.*
import java.lang.management.ManagementFactory
import java.util.*

/**
 * Adapter to run a router inside a Servlets container. It is not a standard engine as it is not
 * started/stopped (not passed to an [HttpServer]).
 */
abstract class ServletServer(
    private val handler: HttpHandler = OnHandler { this },
    private val settings: HttpServerSettings = HttpServerSettings(),
) : ServletContextListener {

    private companion object {
        val logger: Logger = Logger(ServletServer::class)
    }

    override fun contextInitialized(sce: ServletContextEvent) {
        val startTimestamp = System.nanoTime()

        val servletFilter = ServletFilter(handler)
        // Let's be a good JEE citizen
        val servletContext = sce.servletContext
        servletFilter.init(object : FilterConfig {
            val params = Hashtable(1).apply { put("filterName", filterName) }
            override fun getFilterName(): String = ServletFilter::class.java.name
            override fun getServletContext(): ServletContext = servletContext
            override fun getInitParameter(name: String): String = params.require(name)
            override fun getInitParameterNames(): Enumeration = params.keys()
        })
        val filter = servletContext.addFilter("filters", servletFilter)
        filter.addMappingForUrlPatterns(EnumSet.allOf(DispatcherType::class.java), true, "/*")

        logger.info { "Server started\n${createBanner(System.nanoTime() - startTimestamp)}" }
    }

    override fun contextDestroyed(sce: ServletContextEvent?) {
        logger.info { "Server context destroyed" }
    }

    private fun createBanner(startUpTimestamp: Long): String {

        val heap = ManagementFactory.getMemoryMXBean().heapMemoryUsage
        val jvmMemory = "%,d".format(heap.init / 1024)
        val usedMemory = "%,d".format(heap.used / 1024)
        val bootTime = "%01.3f".format(ManagementFactory.getRuntimeMXBean().uptime / 1e3)
        val startUpTime = "%,.0f".format(startUpTimestamp / 1e6)

        val serverAdapterValue = "$BOLD$CYAN${javaClass.simpleName}$RESET"

        val hostnameValue = "$BLUE${Jvm.hostName}$RESET"
        val cpuCountValue = "$BLUE${Jvm.cpuCount}$RESET"
        val jvmMemoryValue = "$BLUE$jvmMemory$RESET"

        val javaVersionValue = "$BOLD${BLUE}Java ${Jvm.version}$RESET [$BLUE${Jvm.name}$RESET]"

        val localeValue = "$BLUE${Jvm.localeCode}$RESET"
        val timezoneValue = "$BLUE${Jvm.timeZone.id}$RESET"
        val charsetValue = "$BLUE${Jvm.charset}$RESET"

        val bootTimeValue = "$BOLD$MAGENTA$bootTime s$RESET"
        val startUpTimeValue = "$BOLD$MAGENTA$startUpTime ms$RESET"
        val usedMemoryValue = "$BOLD$MAGENTA$usedMemory KB$RESET"

        val information = """

            Server Adapter: $serverAdapterValue

            🖥️️ Running in '$hostnameValue' with $cpuCountValue CPUs $jvmMemoryValue KB
            🛠 Using $javaVersionValue
            🌍 Locale: $localeValue Timezone: $timezoneValue Charset: $charsetValue

            ⏱ Started in $bootTimeValue (server: $startUpTimeValue) using $usedMemoryValue
            🚀 Served at a JEE Server

        """.trimIndent()

        val banner = (settings.banner?.let { "$it\n" } ?: HttpServer.banner) + information
        return banner.prependIndent()
    }
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy