8000 Upgraded ktor to version 2.2.2 (#51) · icerockdev/web-utils@2c4e267 · GitHub
[go: up one dir, main page]

Skip to content

Commit 2c4e267

Browse files
authored
Upgraded ktor to version 2.2.2 (#51)
* Upgrade ktor to version 2.2.2, up kotlin version * Fixed after sonatype lift review
1 parent c4522d6 commit 2c4e267

File tree

15 files changed

+218
-169
lines changed

15 files changed

+218
-169
lines changed

README.md

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@ repositories {
1212
}
1313

1414
// Append dependency
15-
implementation("com.icerockdev:web-utils:0.10.1")
15+
implementation("com.icerockdev:web-utils:1.0.0")
1616
````
1717

1818
## Library usage
@@ -23,7 +23,8 @@ Lib include tools for:
2323
- Localization support tools
2424
- Validation support tools
2525
- Query params parser to Object (include ktor feature with required fields)
26-
- JsonDataLogger - log request and response data via MDC, working by CallLogging
26+
- ApplicationCallLogging - a plugin that allows you to log incoming client requests and server responses
27+
- JsonDataLogger - log request and response data via MDC, working by ApplicationCallLogging
2728

2829
## TODO
2930
- Support multiple connectors from HOCON file

gradle.properties

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -4,12 +4,12 @@ org.gradle.parallel=true
44
org.gradle.caching=true
55

66
kotlin.code.style=official
7-
kotlin_version=1.6.10
8-
ktor_version=1.6.8
9-
logback_version=1.2.11
7+
kotlin_version=1.7.21
8+
ktor_version=2.2.2
9+
logback_version=1.4.5
1010
jodatime_version = 2.10.6
1111
# Validation
12-
javax_validation=2.0.0.Final
12+
javax_validation=2.0.1.Final
1313
javax_el_version=2.2.6
1414
javax_el_api_version=3.0.0
1515
beanutils_version=1.9.4

sample/build.gradle.kts

Lines changed: 7 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@ plugins {
1414
}
1515

1616
group = "com.icerockdev"
17-
version = "0.0.1"
17+
version = "1.0.0"
1818

1919
apply(plugin = "kotlin")
2020

@@ -23,12 +23,14 @@ application {
2323
}
2424

2525
dependencies {
26-
implementation("biz.paluch.logging:logstash-gelf:1.13.0")
26+
implementation("biz.paluch.logging:logstash-gelf:1.15.0")
2727

2828
implementation(project(":web-utils"))
29+
implementation("io.ktor:ktor-serialization-jackson:${properties["ktor_version"]}")
2930

3031
// tests
3132
testImplementation("io.ktor:ktor-server-tests:${properties["ktor_version"]}")
33+
testImplementation("io.ktor:ktor-client-content-negotiation:${properties["ktor_version"]}")
3234
}
3335

3436
java {
@@ -47,7 +49,8 @@ val jar by tasks.getting(Jar::class) {
4749
destinationDirectory.set(file("${project.rootDir}/build"))
4850
manifest {
4951
attributes["Main-Class"] = application.mainClass.get()
50-
attributes["Class-Path"] =
51-
configurations.runtimeClasspath.get().filter { it.name.endsWith("jar") }.joinToString { "libs/${it.name}" }
52+
attributes["Class-Path"] = configurations.runtimeClasspath.get().filter {
53+
it.name.endsWith("jar")
54+
}.joinToString { "libs/${it.name}" }
5255
}
5356
}

sample/collection.http

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,11 @@ Accept: text/plain
33

44
###
55

6+
GET http://127.0.0.1:8080/not-found
7+
Accept: text/plain
8+
9+
###
10+
611
GET http://127.0.0.1:8080/object
712
Accept: application/json
813

sample/src/main/kotlin/com/icerockdev/sample/server.kt

Lines changed: 55 additions & 49 deletions
Original file line numberDiff line numberDiff line change
@@ -26,21 +26,23 @@ import com.icerockdev.webserver.log.JsonSecret
2626
import com.icerockdev.webserver.log.LoggingConfiguration
2727
import com.icerockdev.webserver.log.jsonLogger
2828
import com.icerockdev.webserver.tools.receiveRequest
29-
import io.ktor.application.Application
30-
import io.ktor.application.ApplicationCall
31-
import io.ktor.application.call
32-
import io.ktor.application.install
33-
import io.ktor.features.CORS
34-
import io.ktor.features.CallId
35-
import io.ktor.features.ContentNegotiation
36-
import io.ktor.features.DefaultHeaders
37-
import io.ktor.features.StatusPages
38-
import io.ktor.jackson.jackson
39-
import io.ktor.response.respond
40-
import io.ktor.routing.get
41-
import io.ktor.routing.post
42-
import io.ktor.routing.put
43-
import io.ktor.routing.routing
29+
import io.ktor.http.HttpStatusCode
30+
import io.ktor.serialization.jackson.jackson
31+
import io.ktor.server.application.Application
32+
import io.ktor.server.application.ApplicationCall
33+
import io.ktor.server.application.call
34+
import io.ktor.server.application.install
35+
import io.ktor.server.plugins.callid.CallId
36+
import io.ktor.server.plugins.contentnegotiation.ContentNegotiation
37+
import io.ktor.server.plugins.cors.routing.CORS
38+
import io.ktor.server.plugins.defaultheaders.DefaultHeaders
39+
import io.ktor.server.plugins.statuspages.StatusPages
40+
import io.ktor.server.response.respond
41+
import io.ktor.server.routing.Routing
42+
import io.ktor.server.routing.get
43+
import io.ktor.server.routing.post
44+
import io.ktor.server.routing.put
45+
import io.ktor.server.routing.routing
4446
import org.slf4j.LoggerFactory
4547

4648
fun Application.main() {
@@ -89,53 +91,57 @@ fun Application.main() {
8991
}
9092

9193
routing {
92-
get("/object") {
93-
call.respond(TestResponse(200, "some message"))
94-
}
94+
setupSampleRouting()
95+
}
96+
}
9597

96-
jsonLogger {
97-
get("/") {
98-
call.respond("!!!")
99-
}
98+
private fun Routing.setupSampleRouting() {
99+
get("/object") {
100+
call.respond(TestResponse(HttpStatusCode.OK.value, "some message without JsonLogger plugin"))
101+
}
100102

101-
post("/object") {
102-
val request = call.receiveRequest<TestRequest>()
103-
if (!request.validate()) {
104-
throw ValidationException(request.getErrorList())
105-
}
106-
call.respond(TestResponse2(200, request.email, request.password))
107-
}
103+
jsonLogger {
104+
get("/") {
105+
call.respond("!!!")
106+
}
108107

109-
put("/object") {
110-
val request = call.receiveRequest<TestRequest>()
111-
if (!request.validate()) {
112-
throw ValidationException(request.getErrorList())
113-
}
114-
call.respond(TestResponse2(200, request.email, request.password))
108+
post("/object") {
109+
val request = call.receiveRequest<TestRequest>()
110+
if (!request.validate()) {
111+
throw ValidationException(request.getErrorList())
115112
}
113+
call.respond(TestResponse2(HttpStatusCode.OK.value, request.email, request.password))
114+
}
116115

117-
get("/custom-object") {
118-
call.respond(CustomResponse(200, "Custom message", listOf(1, 2, 3)))
116+
put("/object") {
117+
val request = call.receiveRequest<TestRequest>()
118+
if (!request.validate()) {
119+
throw ValidationException(request.getErrorList())
119120
}
121+
call.respond(TestResponse2(HttpStatusCode.OK.value, request.email, request.password))
122+
}
120123

121-
get("/exception") {
122-
throw RuntimeException("Some exception")
123-
}
124+
get("/custom-object") {
125+
call.respond(CustomResponse(HttpStatusCode.OK.value, "Custom message", listOf(1, 2, 3)))
126+
}
124127

125-
get("/handled") {
126-
throw ServerErrorException("Some handled exception")
127-
}
128+
get("/exception") {
129+
throw UnsupportedOperationException("Some exception")
130+
}
128131

129-
get("/get") {
130-
val params = call.receiveQuery<QueryValues>()
131-
call.respond(object : AbstractResponse(200, params.toString()) {})
132-
}
132+
get("/handled") {
133+
throw ServerErrorException("Some handled exception")
133134
}
134135

135-
get("/handled2") {
136-
throw ForbiddenException("Some handled exception")
136+
get("/get") {
137+
val params = call.receiveQuery<QueryValues>()
138+
call.respond(object : AbstractResponse(HttpStatusCode.OK.value, params.toString()) {})
137139
}
138140
}
141+
142+
get("/handled2") {
143+
throw ForbiddenException("Some handled exception")
144+
}
139145
}
140146

141147
class TestRequest(@field:StrictEmail val email: String, @JsonSecret val password: String) : Request()

sample/src/test/kotlin/SampleTest.kt

Lines changed: 38 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,19 @@
1+
import com.fasterxml.jackson.databind.SerializationFeature
12
import com.fasterxml.jackson.module.kotlin.jacksonObjectMapper
2-
import com.fasterxml.jackson.module.kotlin.jacksonTypeRef
33
import com.icerockdev.sample.CustomResponse
44
import com.icerockdev.sample.QueryValues
55
import com.icerockdev.sample.TestResponse
6-
import com.icerockdev.sample.main
6+
import com.icerockdev.webserver.applyDefaultConfiguration
7+
import io.ktor.client.HttpClient
8+
import io.ktor.client.call.body
9+
import io.ktor.client.plugins.contentnegotiation.ContentNegotiation
10+
import io.ktor.client.request.get
11+
import io.ktor.client.request.header
712
import io.ktor.http.HttpHeaders
8-
import io.ktor.http.HttpMethod
913
import io.ktor.http.HttpStatusCode
10-
import io.ktor.server.testing.handleRequest
11-
import io.ktor.server.testing.withTestApplication
14+
import io.ktor.serialization.jackson.jackson
15+
import io.ktor.server.testing.ApplicationTestBuilder
16+
import io.ktor.server.testing.testApplication
1217
import org.junit.Assert
1318
import org.junit.Test
1419

@@ -24,31 +29,41 @@ class SampleTest {
2429
test = listOf("string"),
2530
tmp = listOf(1, 2, 3)
2631
)
27-
withTestApplication(moduleFunction = { main() }) {
28-
handleRequest(HttpMethod.Get, "/get?age=5&testValue=1&email=test@test.e&test=string&tmp=1&tmp=2&tmp=3") {
29-
addHeader(HttpHeaders.Accept, "application/json")
30-
addHeader(HttpHeaders.ContentType, "application/json")
31-
}.apply {
32-
Assert.assertEquals(HttpStatusCode.OK.value, response.status()?.value)
33-
val result = mapper.readValue(response.content, jacksonTypeRef<TestResponse>())
34-
Assert.assertNotNull(result)
35-
Assert.assertEquals(query.toString(), result?.message)
32+
testApplication {
33+
val response = getClient().get("/get?age=5&testValue=1&email=test@test.e&test=string&tmp=1&tmp=2&tmp=3") {
34+
header(HttpHeaders.Accept, "application/json")
35+
header(HttpHeaders.ContentType, "application/json")
3636
}
37+
Assert.assertEquals(HttpStatusCode.OK.value, response.status.value)
38+
val result: TestResponse? = response.body()
39+
Assert.assertNotNull(result)
40+
Assert.assertEquals(query.toString(), result?.message)
41+
3742
}
3843
}
3944

4045
@Test
4146
fun `test custom object`() {
4247
val customResponse = CustomResponse(200, "Custom message", listOf(1, 2, 3))
43-
withTestApplication(moduleFunction = { main() }) {
44-
handleRequest(HttpMethod.Get, "/custom-object") {
45-
addHeader(HttpHeaders.Accept, "application/json")
46-
addHeader(HttpHeaders.ContentType, "application/json")
47-
}.apply {
48-
Assert.assertEquals(HttpStatusCode.OK.value, response.status()?.value)
49-
val result = mapper.readValue(response.content, jacksonTypeRef<CustomResponse>())
50-
Assert.assertNotNull(result)
51-
Assert.assertEquals(mapper.writeValueAsString(customResponse), mapper.writeValueAsString(result))
48+
testApplication {
49+
val response = getClient().get("/custom-object") {
50+
header(HttpHeaders.Accept, "application/json")
51+
header(HttpHeaders.ContentType, "application/json")
52+
}
53+
54+
Assert.assertEquals(HttpStatusCode.OK.value, response.status.value)
55+
val result: CustomResponse? = response.body()
56+
Assert.assertNotNull(result)
57+
Assert.assertEquals(mapper.writeValueAsString(customResponse), mapper.writeValueAsString(result))
58+
59+
}
60+
}
61+
62+
private fun ApplicationTestBuilder.getClient(): HttpClient = createClient {
63+
install(ContentNegotiation) {
64+
jackson {
65+
applyDefaultConfiguration()
66+
configure(SerializationFeature.INDENT_OUTPUT, false)
5267
}
5368
}
5469
}

settings.gradle.kts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,7 @@ include(":web-utils")
2828

2929
val properties: Map<String, String> = startParameter.projectProperties
3030

31-
// ./gradlew -PlibraryPublish publishToMavenLocal
31+
// ./gradlew -PlibraryPublish -PlibraryPublishToMavenLocal publishToMavenLocal
3232
// ./gradlew :web-utils:publish -PlibraryPublish
3333
val libraryPublish: Boolean = properties.containsKey("libraryPublish")
3434
if(!libraryPublish) {

web-utils/build.gradle.kts

Lines changed: 14 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@ apply(plugin = "java")
1717
apply(plugin = "kotlin")
1818

1919
group = "com.icerockdev"
20-
version = "0.10.1"
20+
version = "1.0.0"
2121

2222
val sourcesJar by tasks.registering(Jar::class) {
2323
archiveClassifier.set("sources")
@@ -29,17 +29,27 @@ dependencies {
2929
implementation("ch.qos.logback:logback-classic:${properties["logback_version"]}")
3030
// ktor
3131
api("io.ktor:ktor-server-core:${properties["ktor_version"]}")
32+
api("io.ktor:ktor-server-cors:${properties["ktor_version"]}")
33+
api("io.ktor:ktor-server-call-logging:${properties["ktor_version"]}")
34+
api("io.ktor:ktor-server-status-pages:${properties["ktor_version"]}")
35+
api("io.ktor:ktor-server-call-id:${properties["ktor_version"]}")
36+
api("io.ktor:ktor-server-content-negotiation:${properties["ktor_version"]}")
37+
api("io.ktor:ktor-server-default-headers-jvm:${properties["ktor_version"]}")
3238
implementation("io.ktor:ktor-server-netty:${properties["ktor_version"]}")
3339

3440
api("joda-time:joda-time:${properties["jodatime_version"]}")
3541

3642
// json
37-
api("io.ktor:ktor-jackson:${properties["ktor_version"]}")
43+
api("io.kto C2EE r:ktor-serialization-jackson:${properties["ktor_version"]}")
3844

3945
// javax
4046
api("javax.validation:validation-api:${properties["javax_validation"]}")
4147
api("org.hibernate.validator:hibernate-validator:${properties["hibernate_validator_version"]}")
42-
api("org.hibernate.validator:hibernate-validator-annotation-processor:${properties["hibernate_validator_annotation_processor_version"]}")
48+
api(
49+
group = "org.hibernate.validator",
50+
name = "hibernate-validator-annotation-processor",
51+
version = properties["hibernate_validator_annotation_processor_version"].toString()
52+
)
4353
api("javax.el:javax.el-api:${properties["javax_el_api_version"]}")
4454
api("org.glassfish.web:javax.el:${properties["javax_el_version"]}")
4555
api("commons-beanutils:commons-beanutils:${properties["beanutils_version"]}")
@@ -123,6 +133,7 @@ publishing {
123133
}
124134

125135
signing {
136+
setRequired({!properties.containsKey("libraryPublishToMavenLocal")})
126137
val signingKeyId: String? = System.getenv("SIGNING_KEY_ID")
127138
val signingPassword: String? = System.getenv("SIGNING_PASSWORD")
128139
val signingKey: String? = System.getenv("SIGNING_KEY")?.let { base64Key ->

web-utils/src/main/kotlin/com/icerockdev/api/request/Pagination.kt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@
44

55
package com.icerockdev.api.request
66

7-
import io.ktor.application.ApplicationCall
7+
import io.ktor.server.application.ApplicationCall
88

99
class Pagination(
1010
val limit: Int = 10,

web-utils/src/main/kotlin/com/icerockdev/api/request/QueryParser.kt

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -8,11 +8,11 @@ import com.fasterxml.jackson.databind.ObjectMapper
88
import com.fasterxml.jackson.module.kotlin.jacksonObjectMapper
99
import com.fasterxml.jackson.module.kotlin.jacksonTypeRef
1010
import com.icerockdev.exception.BadRequestException
11-
import io.ktor.application.ApplicationCall
12-
import io.ktor.application.ApplicationCallPipeline
13-
import io.ktor.application.ApplicationFeature
14-
import io.ktor.application.call
15-
import io.ktor.application.log
11+
import io.ktor.server.application.ApplicationCall
12+
import io.ktor.server.application.ApplicationCallPipeline
13+
import io.ktor.server.application.BaseApplicationPlugin
14+
import io.ktor.server.application.call
15+
import io.ktor.server.application.log
1616
import io.ktor.util.AttributeKey
1717
import io.ktor.util.pipeline.PipelinePhase
1818

@@ -26,9 +26,9 @@ class QueryParser(val mapper: ObjectMapper, val errorLogging: Boolean) {
2626
}
2727

2828
/**
29-
* Implementation of an [ApplicationFeature] for the [QueryParser]
29+
* Implementation of an [BaseApplicationPlugin] for the [QueryParser]
3030
*/
31-
companion object Feature : ApplicationFeature<ApplicationCallPipeline, Configuration, QueryParser> {
31+
companion object Plugin : BaseApplicationPlugin<ApplicationCallPipeline, Configuration, QueryParser> {
3232
override val key = queryParserAttributeKey
3333

3434
override fun install(

0 commit comments

Comments
 (0)
0