Skip to content

Commit

Permalink
Support for Ktor 2
Browse files Browse the repository at this point in the history
This release upgrades the dependencies of this project to support the latest breaking release of Ktor. Going forward only Ktor 2+ will be supported.
  • Loading branch information
HaydenMeloche committed Apr 24, 2022
1 parent cbec8ed commit cf720a7
Show file tree
Hide file tree
Showing 5 changed files with 65 additions and 69 deletions.
5 changes: 3 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@

Khealth is a simple & customizable health plugin for Ktor.

> As of KHealth version `2.0.0`, Ktor 2 is only supported
## Usage

```kotlin
Expand Down Expand Up @@ -118,7 +119,7 @@ For Maven:
<dependency>
<groupId>dev.hayden</groupId>
<artifactId>khealth</artifactId>
<version>1.1.0</version>
<version>2.0.0</version>
</dependency>
```

Expand All @@ -132,7 +133,7 @@ allprojects {
```
```groovy
dependencies {
implementation 'dev.hayden:khealth:1.1.0'
implementation 'dev.hayden:khealth:2.0.0'
}
```

Expand Down
23 changes: 16 additions & 7 deletions pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
<modelVersion>4.0.0</modelVersion>
<groupId>dev.hayden</groupId>
<artifactId>khealth</artifactId>
<version>1.1.0</version>
<version>2.0.0</version>
<packaging>jar</packaging>
<name>khealth</name>

Expand All @@ -22,8 +22,8 @@
<properties>
<junit.jupiter.version>5.8.2</junit.jupiter.version>
<kotlin.compiler.jvmTarget>1.8</kotlin.compiler.jvmTarget>
<kotlin.version>1.6.10</kotlin.version>
<ktor.version>1.6.7</ktor.version>
<kotlin.version>1.6.20</kotlin.version>
<ktor.version>2.0.0</ktor.version>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<serialization.version>1.3.2</serialization.version>
</properties>
Expand All @@ -36,13 +36,17 @@
</dependency>
<dependency>
<groupId>io.ktor</groupId>
<artifactId>ktor-server-test-host</artifactId>
<artifactId>ktor-server-core-jvm</artifactId>
<version>${ktor.version}</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>io.ktor</groupId>
<artifactId>ktor-auth</artifactId>
<artifactId>ktor-server-test-host-jvm</artifactId>
<version>${ktor.version}</version>
</dependency>
<dependency>
<groupId>io.ktor</groupId>
<artifactId>ktor-server-auth-jvm</artifactId>
<version>${ktor.version}</version>
<scope>test</scope>
</dependency>
Expand Down Expand Up @@ -81,6 +85,11 @@
<id>mavenCentral</id>
<url>https://repo1.maven.org/maven2/</url>
</repository>
<repository>
<!--Only required if using EAP releases -->
<id>ktor-eap</id>
<url>https://maven.pkg.jetbrains.space/public/p/ktor/eap</url>
</repository>
</repositories>

<build>
Expand Down Expand Up @@ -144,7 +153,7 @@
<plugin>
<groupId>org.jetbrains.kotlin</groupId>
<artifactId>kotlin-maven-plugin</artifactId>
<version>1.6.10</version>
<version>${kotlin.version}</version>
<configuration>
<compilerPlugins>
<plugin>kotlinx-serialization</plugin>
Expand Down
84 changes: 35 additions & 49 deletions src/main/kotlin/KHealth.kt → src/main/kotlin/KHealthPlugin.kt
Original file line number Diff line number Diff line change
@@ -1,58 +1,57 @@
package dev.hayden

import io.ktor.application.Application
import io.ktor.application.ApplicationCallPipeline
import io.ktor.application.ApplicationFeature
import io.ktor.application.call
import io.ktor.application.featureOrNull
import io.ktor.application.install
import io.ktor.http.ContentType
import io.ktor.http.HttpStatusCode
import io.ktor.response.respondText
import io.ktor.routing.Route
import io.ktor.routing.Routing
import io.ktor.routing.get
import io.ktor.routing.route
import io.ktor.util.AttributeKey
import io.ktor.server.application.ApplicationCall
import io.ktor.server.application.createApplicationPlugin
import io.ktor.server.application.install
import io.ktor.server.application.pluginOrNull
import io.ktor.server.response.respondText
import io.ktor.server.routing.Route
import io.ktor.server.routing.Routing
import io.ktor.server.routing.get
import io.ktor.server.routing.route
import kotlinx.serialization.encodeToString
import kotlinx.serialization.json.Json

data class Check(val checkName: String, val check: CheckFunction)
typealias CheckFunction = suspend () -> Boolean

class KHealth private constructor(private val config: KHealthConfiguration) {
val KHealth = createApplicationPlugin(
name = "KHealth",
createConfiguration = ::KHealthConfiguration,
body = {
onCall { call ->
KHealthPlugin(this.pluginConfig).apply { interceptor(call) }
}
}
)

class KHealthPlugin internal constructor(private val config: KHealthConfiguration) {

/**
* Interceptor that handles all http requests. If either the health check or ready endpoint are
* called it will return a custom response with the result of each custom check if any are defined.
*/
fun interceptor(pipeline: Application) {
pipeline.intercept(ApplicationCallPipeline.Monitoring) {
val routing: Routing.() -> Unit = {
val routing: Route.() -> Unit = {
if (config.readyCheckEnabled) route(config.readyCheckPath) {
get {
val (status, responseBody) = processChecks(config.readyChecks)
call.respondText(responseBody, ContentType.Application.Json, status)
finish()
}
fun interceptor(call: ApplicationCall) {
val routing: Routing.() -> Unit = {
val routing: Route.() -> Unit = {
if (config.readyCheckEnabled) route(config.readyCheckPath) {
get {
val (status, responseBody) = processChecks(config.readyChecks)
call.respondText(responseBody, ContentType.Application.Json, status)
}
if (config.healthCheckEnabled) route(config.healthCheckPath) {
get {
val (status, responseBody) = processChecks(config.healthChecks)
call.respondText(responseBody, ContentType.Application.Json, status)
finish()
}
}
if (config.healthCheckEnabled) route(config.healthCheckPath) {
get {
val (status, responseBody) = processChecks(config.healthChecks)
call.respondText(responseBody, ContentType.Application.Json, status)
}
}

config.wrapWith?.invoke(this, routing) ?: routing(this)
}

pipeline.featureOrNull(Routing)?.apply(routing) ?: pipeline.install(Routing, routing)

proceed()
config.wrapWith?.invoke(this, routing) ?: routing(this)
}
call.application.pluginOrNull(Routing)?.apply(routing) ?: call.application.install(Routing, routing)
}

/**
Expand All @@ -69,23 +68,10 @@ class KHealth private constructor(private val config: KHealthConfiguration) {
} else HttpStatusCode.OK
return Pair(status, Json.encodeToString(checksWithResults))
}

/**
* KHealth is a small health check library designed for Ktor. It supports both a 'health' endpoint and
* a 'ready' endpoint. Both can be customized with custom checks or completely disabled through [KHealthConfiguration].
* @author Hayden Meloche
*/
companion object Feature : ApplicationFeature<Application, KHealthConfiguration, KHealth> {
override val key = AttributeKey<KHealth>("KHealth")
override fun install(
pipeline: Application,
configure: KHealthConfiguration.() -> Unit
) = KHealth(KHealthConfiguration().apply(configure)).apply { interceptor(pipeline) }
}
}

/**
* Configuration class used to configure [KHealth]. No values are required to be passed in as defaults
* Configuration class used to configure [KHealthPlugin]. No values are required to be passed in as defaults
* are provided.
*/
class KHealthConfiguration internal constructor() {
Expand Down
12 changes: 6 additions & 6 deletions src/test/kotlin/KHealthSetups.kt
Original file line number Diff line number Diff line change
@@ -1,11 +1,11 @@
import KHealthTest.Companion.helloRoute
import dev.hayden.KHealth
import io.ktor.application.Application
import io.ktor.application.install
import io.ktor.auth.UserIdPrincipal
import io.ktor.auth.authenticate
import io.ktor.auth.authentication
import io.ktor.auth.basic
import io.ktor.server.application.Application
import io.ktor.server.application.install
import io.ktor.server.auth.UserIdPrincipal
import io.ktor.server.auth.authenticate
import io.ktor.server.auth.authentication
import io.ktor.server.auth.basic

/**
* A basic configuration of [KHealth] with nothing but defaults
Expand Down
10 changes: 5 additions & 5 deletions src/test/kotlin/KHealthTest.kt
Original file line number Diff line number Diff line change
@@ -1,10 +1,10 @@
import io.ktor.application.Application
import io.ktor.application.call
import io.ktor.http.HttpMethod
import io.ktor.http.HttpStatusCode
import io.ktor.response.respondText
import io.ktor.routing.get
import io.ktor.routing.routing
import io.ktor.server.application.Application
import io.ktor.server.application.call
import io.ktor.server.response.respondText
import io.ktor.server.routing.get
import io.ktor.server.routing.routing
import io.ktor.server.testing.TestApplicationEngine
import io.ktor.server.testing.handleRequest
import io.ktor.server.testing.withTestApplication
Expand Down

0 comments on commit cf720a7

Please sign in to comment.