Skip to content

Commit 53b93df

Browse files
committed
build(model-server): migrate to ktor 3
1 parent f3030bc commit 53b93df

File tree

15 files changed

+71
-135
lines changed

15 files changed

+71
-135
lines changed

authorization/src/main/kotlin/org/modelix/authorization/KtorAuthUtils.kt

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@ import io.ktor.server.auth.parseAuthorizationHeader
1515
import io.ktor.server.auth.principal
1616
import io.ktor.server.request.header
1717
import io.ktor.server.routing.Route
18-
import io.ktor.util.pipeline.PipelineContext
18+
import io.ktor.server.routing.RoutingContext
1919
import org.modelix.authorization.permissions.PermissionEvaluator
2020
import org.modelix.authorization.permissions.PermissionInstanceReference
2121
import org.modelix.authorization.permissions.PermissionParts
@@ -35,7 +35,7 @@ fun Route.requiresLogin(body: Route.() -> Unit) {
3535
}
3636
}
3737

38-
fun PipelineContext<*, ApplicationCall>.checkPermission(permissionParts: PermissionParts) {
38+
fun RoutingContext.checkPermission(permissionParts: PermissionParts) {
3939
call.checkPermission(permissionParts)
4040
}
4141

@@ -83,7 +83,7 @@ fun ApplicationCall.jwtFromHeaders(): DecodedJWT? {
8383

8484
fun ApplicationCall.jwt() = principal<AccessTokenPrincipal>()?.jwt ?: jwtFromHeaders()
8585

86-
fun PipelineContext<Unit, ApplicationCall>.getUserName(): String? {
86+
fun RoutingContext.getUserName(): String? {
8787
return call.getUserName()
8888
}
8989

authorization/src/main/kotlin/org/modelix/authorization/PermissionManagementPage.kt

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,13 @@
11
package org.modelix.authorization
22

33
import io.ktor.server.application.ApplicationCall
4-
import io.ktor.server.application.application
5-
import io.ktor.server.application.call
64
import io.ktor.server.application.plugin
75
import io.ktor.server.auth.principal
86
import io.ktor.server.html.respondHtml
97
import io.ktor.server.request.receiveParameters
108
import io.ktor.server.response.respond
119
import io.ktor.server.routing.Route
10+
import io.ktor.server.routing.application
1211
import io.ktor.server.routing.get
1312
import io.ktor.server.routing.post
1413
import io.ktor.server.routing.route

kotlin-js-store/yarn.lock

Lines changed: 1 addition & 43 deletions
Original file line numberDiff line numberDiff line change
@@ -60,13 +60,6 @@ abab@^2.0.6:
6060
resolved "https://registry.yarnpkg.com/abab/-/abab-2.0.6.tgz#41b80f2c871d19686216b82309231cfd3cb3d291"
6161
integrity sha512-j2afSsaIENvHZN2B8GOpF566vZ5WVk5opAiMTvWgaQT8DkbOqsTfvNAvHoRGU2zzP8cPoqys+xHTRDWW8L+/BA==
6262

63-
64-
version "3.0.0"
65-
resolved "https://registry.yarnpkg.com/abort-controller/-/abort-controller-3.0.0.tgz#eaf54d53b62bae4138e809ca225c8439a6efb392"
66-
integrity sha512-h8lQ8tacZYnR3vNQTgibj+tODHI5/+l06Au2Pcriv/Gmet0eaj4TwWH41sO9wnHDiQsEj19q0drzdWdeAHtweg==
67-
dependencies:
68-
event-target-shim "^5.0.0"
69-
7063
acorn-globals@^7.0.0:
7164
version "7.0.1"
7265
resolved "https://registry.yarnpkg.com/acorn-globals/-/acorn-globals-7.0.1.tgz#0dbf05c44fa7c94332914c02066d5beff62c40c3"
@@ -336,11 +329,6 @@ esutils@^2.0.2:
336329
resolved "https://registry.yarnpkg.com/esutils/-/esutils-2.0.3.tgz#74d2eb4de0b8da1293711910d50775b9b710ef64"
337330
integrity sha512-kVscqXk4OCp68SZ0dkgEKVi6/8ij300KBWTJq32P/dYeWTSwK41WyTxalN1eRmA5Z9UU/LX9D7FWSmV9SAYx6g==
338331

339-
event-target-shim@^5.0.0:
340-
version "5.0.1"
341-
resolved "https://registry.yarnpkg.com/event-target-shim/-/event-target-shim-5.0.1.tgz#5d4d3ebdf9583d63a5333ce2deb7480ab2b05789"
342-
integrity sha512-i/2XbnSz/uxRCU6+NdVJgKWDTM427+MqYbkQzD321DuCQJUqOuJKIA0IM2+W2xtYHdKOmZ4dR6fExsd4SXL+WQ==
343-
344332
fast-levenshtein@~2.0.6:
345333
version "2.0.6"
346334
resolved "https://registry.yarnpkg.com/fast-levenshtein/-/fast-levenshtein-2.0.6.tgz#3d8a5c66883a16a30ca8643e851f19baa7797917"
@@ -650,13 +638,6 @@ ms@^2.1.3:
650638
resolved "https://registry.yarnpkg.com/ms/-/ms-2.1.3.tgz#574c8138ce1d2b5861f0b44579dbadd60c6615b2"
651639
integrity sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==
652640

653-
654-
version "2.6.7"
655-
resolved "https://registry.yarnpkg.com/node-fetch/-/node-fetch-2.6.7.tgz#24de9fba827e3b4ae44dc8b20256a379160052ad"
656-
integrity sha512-ZjMPFEfVx5j+y2yF35Kzx5sF7kDzxuDj6ziH4FFbOp87zKDZNx8yExJIb05OGF4Nlt9IHFIMBkRl41VdvcNdbQ==
657-
dependencies:
658-
whatwg-url "^5.0.0"
659-
660641
normalize-path@^3.0.0, normalize-path@~3.0.0:
661642
version "3.0.0"
662643
resolved "https://registry.yarnpkg.com/normalize-path/-/normalize-path-3.0.0.tgz#0dcd69ff23a1c9b11fd0978316644a0388216a65"
@@ -862,11 +843,6 @@ tr46@^3.0.0:
862843
dependencies:
863844
punycode "^2.1.1"
864845

865-
tr46@~0.0.3:
866-
version "0.0.3"
867-
resolved "https://registry.yarnpkg.com/tr46/-/tr46-0.0.3.tgz#8184fd347dac9cdc185992f3a6622e14b9d9ab6a"
868-
integrity sha512-N3WMsuqV66lT30CrXNbEjx4GEwlow3v6rr4mCcv6prnfwhS01rkgyFdjPNBYd9br7LpXV1+Emh01fHnq2Gdgrw==
869-
870846
tslib@^1.11.1:
871847
version "1.14.1"
872848
resolved "https://registry.yarnpkg.com/tslib/-/tslib-1.14.1.tgz#cf2d38bdc34a134bcaf1091c41f6619e2f672d00"
@@ -914,11 +890,6 @@ w3c-xmlserializer@^3.0.0:
914890
dependencies:
915891
xml-name-validator "^4.0.0"
916892

917-
webidl-conversions@^3.0.0:
918-
version "3.0.1"
919-
resolved "https://registry.yarnpkg.com/webidl-conversions/-/webidl-conversions-3.0.1.tgz#24534275e2a7bc6be7bc86611cc16ae0a5654871"
920-
integrity sha512-2JAn3z8AR6rjK8Sm8orRC0h/bcl/DqL7tRPdGZ4I1CjdF+EaMLmYxBHyXuKL849eucPFhvBoxMsflfOb8kxaeQ==
921-
922893
webidl-conversions@^7.0.0:
923894
version "7.0.0"
924895
resolved "https://registry.yarnpkg.com/webidl-conversions/-/webidl-conversions-7.0.0.tgz#256b4e1882be7debbf01d05f0aa2039778ea080a"
@@ -944,14 +915,6 @@ whatwg-url@^11.0.0:
944915
tr46 "^3.0.0"
945916
webidl-conversions "^7.0.0"
946917

947-
whatwg-url@^5.0.0:
948-
version "5.0.0"
949-
resolved "https://registry.yarnpkg.com/whatwg-url/-/whatwg-url-5.0.0.tgz#966454e8765462e37644d3626f6742ce8b70965d"
950-
integrity sha512-saE57nupxk6v3HY35+jzBwYa0rKSy0XR8JSxZPwgLr7ys0IBzhGviA1/TUGJLmSVqs8pb9AnvICXEuOHLprYTw==
951-
dependencies:
952-
tr46 "~0.0.3"
953-
webidl-conversions "^3.0.0"
954-
955918
word-wrap@~1.2.3:
956919
version "1.2.3"
957920
resolved "https://registry.yarnpkg.com/word-wrap/-/word-wrap-1.2.3.tgz#610636f6b1f703891bd34771ccb17fb93b47079c"
@@ -976,12 +939,7 @@ wrappy@1:
976939
resolved "https://registry.yarnpkg.com/wrappy/-/wrappy-1.0.2.tgz#b5243d8f3ec1aa35f1364605bc0d1036e30ab69f"
977940
integrity sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ==
978941

979-
980-
version "8.5.0"
981-
resolved "https://registry.yarnpkg.com/ws/-/ws-8.5.0.tgz#bfb4be96600757fe5382de12c670dab984a1ed4f"
982-
integrity sha512-BWX0SWVgLPzYwF8lTzEy1egjhS4S4OEAHfsO8o65WOVsrnSRGaSiUaa9e0ggGlkMTtBlmOpEXiie9RUcBO86qg==
983-
984-
ws@^8.17.1:
942+
[email protected], ws@^8.17.1:
985943
version "8.18.0"
986944
resolved "https://registry.yarnpkg.com/ws/-/ws-8.18.0.tgz#0d7505a6eafe2b0e712d232b42279f53bc289bbc"
987945
integrity sha512-8VbfWfHLbbwu3+N6OKsOMpBdT4kXPDDB9cJk2bJ6mh9ucxdlnNvH1e+roYkKmN9Nxw2yjz7VzeO9oOz2zJ04Pw==

model-client/src/jvmMain/kotlin/org/modelix/model/client/RestWebModelClient.kt

Lines changed: 3 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,7 @@ import io.ktor.util.reflect.TypeInfo
2727
import io.ktor.utils.io.ByteReadChannel
2828
import io.ktor.utils.io.charsets.Charset
2929
import io.ktor.utils.io.core.readText
30+
import io.ktor.utils.io.readRemaining
3031
import kotlinx.coroutines.CancellationException
3132
import kotlinx.coroutines.CoroutineScope
3233
import kotlinx.coroutines.Dispatchers
@@ -53,25 +54,6 @@ import java.net.URLEncoder
5354
import java.nio.charset.StandardCharsets
5455
import java.util.LinkedList
5556
import java.util.concurrent.atomic.AtomicInteger
56-
import kotlin.collections.ArrayList
57-
import kotlin.collections.HashMap
58-
import kotlin.collections.Iterable
59-
import kotlin.collections.LinkedHashMap
60-
import kotlin.collections.List
61-
import kotlin.collections.Map
62-
import kotlin.collections.MutableList
63-
import kotlin.collections.MutableMap
64-
import kotlin.collections.Set
65-
import kotlin.collections.component1
66-
import kotlin.collections.component2
67-
import kotlin.collections.emptyList
68-
import kotlin.collections.emptySet
69-
import kotlin.collections.filter
70-
import kotlin.collections.forEach
71-
import kotlin.collections.iterator
72-
import kotlin.collections.minus
73-
import kotlin.collections.plus
74-
import kotlin.collections.set
7557
import kotlin.time.Duration
7658
import kotlin.time.Duration.Companion.minutes
7759
import kotlin.time.Duration.Companion.seconds
@@ -157,8 +139,8 @@ class RestWebModelClient @JvmOverloads constructor(
157139
contentType: ContentType,
158140
charset: Charset,
159141
typeInfo: TypeInfo,
160-
value: Any,
161-
): OutgoingContent {
142+
value: Any?,
143+
): OutgoingContent? {
162144
return TextContent(value.toString(), contentType)
163145
}
164146
},

model-server-api/src/commonTest/kotlin/org/modelix/model/server/api/v2/VersionDeltaStreamV2Test.kt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,8 @@
11
package org.modelix.model.server.api.v2
22

33
import io.ktor.util.cio.use
4-
import io.ktor.util.toByteArray
54
import io.ktor.utils.io.ByteChannel
5+
import io.ktor.utils.io.toByteArray
66
import io.ktor.utils.io.writeFully
77
import io.ktor.utils.io.writeStringUtf8
88
import kotlinx.coroutines.flow.emptyFlow

model-server/src/main/kotlin/org/modelix/model/server/Main.kt

Lines changed: 10 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -8,14 +8,13 @@ import io.ktor.http.HttpStatusCode
88
import io.ktor.serialization.kotlinx.json.json
99
import io.ktor.server.application.Application
1010
import io.ktor.server.application.ApplicationCall
11-
import io.ktor.server.application.call
1211
import io.ktor.server.application.install
12+
import io.ktor.server.engine.connector
1313
import io.ktor.server.engine.embeddedServer
1414
import io.ktor.server.http.content.staticResources
1515
import io.ktor.server.netty.Netty
16-
import io.ktor.server.netty.NettyApplicationEngine
17-
import io.ktor.server.plugins.callloging.CallLogging
18-
import io.ktor.server.plugins.callloging.processingTimeMillis
16+
import io.ktor.server.plugins.calllogging.CallLogging
17+
import io.ktor.server.plugins.calllogging.processingTimeMillis
1918
import io.ktor.server.plugins.contentnegotiation.ContentNegotiation
2019
import io.ktor.server.plugins.cors.routing.CORS
2120
import io.ktor.server.plugins.forwardedheaders.ForwardedHeaders
@@ -27,7 +26,6 @@ import io.ktor.server.request.path
2726
import io.ktor.server.resources.Resources
2827
import io.ktor.server.response.respondText
2928
import io.ktor.server.routing.IgnoreTrailingSlash
30-
import io.ktor.server.routing.Routing
3129
import io.ktor.server.routing.get
3230
import io.ktor.server.routing.routing
3331
import io.ktor.server.websocket.WebSockets
@@ -68,9 +66,9 @@ import java.io.File
6866
import java.io.FileReader
6967
import java.io.IOException
7068
import java.nio.charset.StandardCharsets
71-
import java.time.Duration
7269
import java.util.Properties
7370
import javax.sql.DataSource
71+
import kotlin.time.Duration.Companion.seconds
7472

7573
object Main {
7674
private val LOG = LoggerFactory.getLogger(Main::class.java)
@@ -172,12 +170,10 @@ object Main {
172170
val modelReplicationServer = ModelReplicationServer(repositoriesManager)
173171
val metricsApi = MetricsApiImpl()
174172

175-
val configureNetty: NettyApplicationEngine.Configuration.() -> Unit = {
176-
this.responseWriteTimeoutSeconds = cmdLineArgs.responseWriteTimeoutSeconds
177-
}
178-
179-
val ktorServer: NettyApplicationEngine = embeddedServer(Netty, port = port, configure = configureNetty) {
180-
install(Routing)
173+
val ktorServer = embeddedServer(Netty, configure = {
174+
connector { this.port = port }
175+
responseWriteTimeoutSeconds = cmdLineArgs.responseWriteTimeoutSeconds
176+
}) {
181177
install(ModelixAuthorization) {
182178
permissionSchema = ModelServerPermissionSchema.SCHEMA
183179
installStatusPages = false
@@ -200,8 +196,8 @@ object Main {
200196
// https://opensource.zalando.com/restful-api-guidelines/#136
201197
install(IgnoreTrailingSlash)
202198
install(WebSockets) {
203-
pingPeriod = Duration.ofSeconds(30)
204-
timeout = Duration.ofSeconds(30)
199+
pingPeriod = 30.seconds
200+
timeout = 30.seconds
205201
maxFrameSize = Long.MAX_VALUE
206202
masking = false
207203
}

model-server/src/main/kotlin/org/modelix/model/server/handlers/AboutApiImpl.kt

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,16 +1,14 @@
11
package org.modelix.model.server.handlers
22

3-
import io.ktor.server.application.ApplicationCall
4-
import io.ktor.server.application.call
53
import io.ktor.server.response.respond
6-
import io.ktor.util.pipeline.PipelineContext
4+
import io.ktor.server.routing.RoutingContext
75
import org.modelix.model.server.MODELIX_VERSION
86

97
/**
108
* Responding information about the model server.
119
*/
1210
object AboutApiImpl : AboutApi() {
13-
override suspend fun PipelineContext<Unit, ApplicationCall>.getAboutInformationV1() {
11+
override suspend fun RoutingContext.getAboutInformationV1() {
1412
val about = AboutV1(MODELIX_VERSION)
1513
call.respond(about)
1614
}

model-server/src/main/kotlin/org/modelix/model/server/handlers/HealthApiImpl.kt

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -2,10 +2,8 @@ package org.modelix.model.server.handlers
22

33
import io.ktor.http.ContentType
44
import io.ktor.http.HttpStatusCode
5-
import io.ktor.server.application.ApplicationCall
6-
import io.ktor.server.application.call
75
import io.ktor.server.response.respondText
8-
import io.ktor.util.pipeline.PipelineContext
6+
import io.ktor.server.routing.RoutingContext
97
import org.modelix.model.server.handlers.KeyValueLikeModelServer.Companion.PROTECTED_PREFIX
108
import org.modelix.model.server.store.RequiresTransaction
119
import org.modelix.model.server.store.StoreManager
@@ -16,7 +14,7 @@ class HealthApiImpl(
1614

1715
private val stores: StoreManager get() = repositoriesManager.stores
1816

19-
override suspend fun PipelineContext<Unit, ApplicationCall>.getHealth() {
17+
override suspend fun RoutingContext.getHealth() {
2018
if (isHealthy()) {
2119
call.respondText(text = "healthy", contentType = ContentType.Text.Plain, status = HttpStatusCode.OK)
2220
} else {

model-server/src/main/kotlin/org/modelix/model/server/handlers/IdsApiImpl.kt

Lines changed: 4 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,10 @@
11
package org.modelix.model.server.handlers
22

33
import io.ktor.server.application.Application
4-
import io.ktor.server.application.ApplicationCall
5-
import io.ktor.server.application.call
64
import io.ktor.server.plugins.origin
75
import io.ktor.server.response.respondText
6+
import io.ktor.server.routing.RoutingContext
87
import io.ktor.server.routing.routing
9-
import io.ktor.util.pipeline.PipelineContext
108
import org.modelix.authorization.getUserName
119
import org.modelix.authorization.requiresLogin
1210
import org.modelix.model.server.store.RequiresTransaction
@@ -19,7 +17,7 @@ class IdsApiImpl(
1917
private val repositoriesManager: IRepositoriesManager,
2018
) : IdsApi() {
2119

22-
override suspend fun PipelineContext<Unit, ApplicationCall>.getServerId() {
20+
override suspend fun RoutingContext.getServerId() {
2321
// Currently, the server ID is initialized in KeyValueLikeModelServer eagerly on startup.
2422
// Should KeyValueLikeModelServer be removed or change,
2523
// RepositoriesManager#maybeInitAndGetSeverId will initialize the server ID lazily on the first request.
@@ -34,11 +32,11 @@ class IdsApiImpl(
3432
call.respondText(serverId)
3533
}
3634

37-
override suspend fun PipelineContext<Unit, ApplicationCall>.getUserId() {
35+
override suspend fun RoutingContext.getUserId() {
3836
call.respondText(call.getUserName() ?: call.request.origin.remoteHost)
3937
}
4038

41-
override suspend fun PipelineContext<Unit, ApplicationCall>.generateClientId() {
39+
override suspend fun RoutingContext.generateClientId() {
4240
call.respondText(repositoriesManager.getStoreManager().getGlobalStoreClient().generateId("clientId").toString())
4341
}
4442

model-server/src/main/kotlin/org/modelix/model/server/handlers/KeyValueLikeModelServer.kt

Lines changed: 7 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@ import io.ktor.server.resources.get
1111
import io.ktor.server.resources.post
1212
import io.ktor.server.resources.put
1313
import io.ktor.server.response.respondText
14+
import io.ktor.server.routing.RoutingContext
1415
import io.ktor.server.routing.routing
1516
import io.ktor.util.pipeline.PipelineContext
1617
import kotlinx.html.br
@@ -211,16 +212,16 @@ class KeyValueLikeModelServer(
211212
}
212213

213214
@RequiresTransaction
214-
fun collect(rootKey: String, callContext: CallContext?): JSONArray {
215+
fun collect(rootKey: String, routingContext: RoutingContext?): JSONArray {
215216
val result = JSONArray()
216217
val processed: MutableSet<String> = HashSet()
217218
val pending: MutableSet<String> = HashSet()
218219
pending.add(rootKey)
219220
while (pending.isNotEmpty()) {
220221
val keys: List<String> = ArrayList(pending)
221222
pending.clear()
222-
if (callContext != null) {
223-
keys.forEach { callContext.checkKeyPermission(it, EPermissionType.READ) }
223+
if (routingContext != null) {
224+
keys.forEach { routingContext.checkKeyPermission(it, EPermissionType.READ) }
224225
}
225226
val values = stores.getGlobalStoreClient(false).getAll(keys)
226227
for (i in keys.indices) {
@@ -253,7 +254,7 @@ class KeyValueLikeModelServer(
253254
}
254255

255256
@RequiresTransaction
256-
private fun CallContext.putEntries(newEntries: Map<String, String?>) {
257+
private fun RoutingContext.putEntries(newEntries: Map<String, String?>) {
257258
val referencedKeys: MutableSet<String> = HashSet()
258259
for ((key, value) in newEntries) {
259260
checkKeyPermission(key, EPermissionType.WRITE)
@@ -326,7 +327,7 @@ class KeyValueLikeModelServer(
326327
}
327328
}
328329

329-
private suspend fun CallContext.respondValue(key: String, value: String?) {
330+
private suspend fun RoutingContext.respondValue(key: String, value: String?) {
330331
if (value == null) {
331332
throw HttpException(HttpStatusCode.NotFound, details = "key '$key' not found")
332333
} else {
@@ -335,7 +336,7 @@ class KeyValueLikeModelServer(
335336
}
336337

337338
@Throws(IOException::class)
338-
private fun CallContext.checkKeyPermission(key: String, type: EPermissionType) {
339+
private fun RoutingContext.checkKeyPermission(key: String, type: EPermissionType) {
339340
val isWrite = type == EPermissionType.WRITE
340341
switchKeyType(
341342
key = key,

0 commit comments

Comments
 (0)