103 lines
3.3 KiB
Kotlin

package be.simplenotes.c2c
import be.simplenotes.c2c.api.Api
import be.simplenotes.c2c.api.ApiUrls
import be.simplenotes.c2c.pdf.PdfCreator
import be.simplenotes.c2c.pdf.StreamFactory
import be.simplenotes.c2c.routes.IndexRoute
import be.simplenotes.c2c.routes.PdfRoute
import be.simplenotes.c2c.routes.RouteRoute
import be.simplenotes.c2c.routes.SearchRoute
import com.mitchellbosecke.pebble.PebbleEngine
import com.mitchellbosecke.pebble.loader.ClasspathLoader
import org.apache.hc.client5.http.impl.DefaultRedirectStrategy
import org.apache.hc.client5.http.impl.classic.HttpClientBuilder
import org.http4k.client.ApacheClient
import org.http4k.contract.ContractRoute
import org.http4k.contract.contract
import org.http4k.contract.openapi.ApiInfo
import org.http4k.contract.openapi.v3.OpenApi3
import org.http4k.core.Filter
import org.http4k.core.Response
import org.http4k.core.Status
import org.http4k.core.then
import org.http4k.filter.RequestFilters
import org.http4k.filter.ServerFilters
import org.http4k.format.Jackson
import org.http4k.server.asServer
import org.koin.core.context.startKoin
import org.koin.core.qualifier.named
import org.koin.dsl.bind
import org.koin.dsl.module
import org.slf4j.LoggerFactory
import java.io.PrintWriter
import java.io.StringWriter
val module = module {
single {
ApacheClient(
HttpClientBuilder
.create()
.setRedirectStrategy(DefaultRedirectStrategy())
.build()
)
}
single { ApiUrls(get()) }
single { Jackson.mapper }
single { Api(get(), get()) }
single { PdfCreator(get()) }
single { StreamFactory(get()) }
single {
PebbleEngine
.Builder()
.loader(ClasspathLoader().apply {
prefix = "views/"
suffix = ".twig"
})
.cacheActive(false)
.build()
}
}
val routes = module {
single(named<SearchRoute>()) { SearchRoute(get()).searchRoute() } bind ContractRoute::class
single(named<RouteRoute>()) { RouteRoute(get()).routeRoute() } bind ContractRoute::class
single(named<PdfRoute>()) { PdfRoute(get(), get()).route() } bind ContractRoute::class
single(named<IndexRoute>()) { IndexRoute(get()).route() } bind ContractRoute::class
}
fun main() {
val koin = startKoin {
modules(module, routes)
}.koin
val appRoutes = koin.getAll<ContractRoute>()
val app = contract {
renderer = OpenApi3(ApiInfo("Camp2Camp", "1.0-SNAPSHOT"), Jackson)
descriptionPath = "/api/swagger.json"
routes.all.addAll(appRoutes)
}
val logger = LoggerFactory.getLogger("Camp2Camp")
val loggingFilter = RequestFilters.Tap {
logger.info("${it.method} ${it.uri}")
}
val catchAll = Filter { next ->
{
try {
next(it)
} catch (e: Exception) {
val sw = StringWriter()
e.printStackTrace(PrintWriter(sw))
logger.error(sw.toString())
Response(Status.INTERNAL_SERVER_ERROR)
}
}
}
catchAll.then(ServerFilters.GZip()).then(loggingFilter).then(app).asServer(CustomApacheServer(4000)).start()
logger.info("Listening on http://localhost:4000")
}