@@ -27,6 +27,7 @@ import io.ktor.server.resources.put
27
27
import io.ktor.server.response.respondText
28
28
import io.ktor.server.routing.routing
29
29
import io.ktor.util.pipeline.PipelineContext
30
+ import kotlinx.coroutines.runBlocking
30
31
import kotlinx.html.br
31
32
import kotlinx.html.div
32
33
import kotlinx.html.h1
@@ -48,12 +49,12 @@ import org.modelix.model.lazy.RepositoryId
48
49
import org.modelix.model.persistent.HashUtil
49
50
import org.modelix.model.server.store.IStoreClient
50
51
import org.modelix.model.server.store.pollEntry
52
+ import org.modelix.model.server.store.runTransactionSuspendable
51
53
import org.modelix.model.server.templates.PageWithMenuBar
52
54
import org.slf4j.LoggerFactory
53
55
import java.io.IOException
54
56
import java.util.*
55
57
import java.util.regex.Pattern
56
- import kotlin.collections.LinkedHashMap
57
58
58
59
val PERMISSION_MODEL_SERVER = " model-server" .asResource()
59
60
val MODEL_SERVER_ENTRY = KeycloakResourceType (" model-server-entry" , KeycloakScope .READ_WRITE_DELETE )
@@ -85,7 +86,7 @@ class KeyValueLikeModelServer(val repositoriesManager: RepositoriesManager) {
85
86
// request to initialize it lazily, would make the code less robust.
86
87
// Each change in the logic of RepositoriesManager#maybeInitAndGetSeverId would need
87
88
// the special conditions in the affected requests to be updated.
88
- repositoriesManager.maybeInitAndGetSeverId()
89
+ runBlocking { repositoriesManager.maybeInitAndGetSeverId() }
89
90
application.apply {
90
91
modelServerModule()
91
92
}
@@ -111,7 +112,11 @@ class KeyValueLikeModelServer(val repositoriesManager: RepositoriesManager) {
111
112
if (isHealthy()) {
112
113
call.respondText(text = " healthy" , contentType = ContentType .Text .Plain , status = HttpStatusCode .OK )
113
114
} else {
114
- call.respondText(text = " not healthy" , contentType = ContentType .Text .Plain , status = HttpStatusCode .InternalServerError )
115
+ call.respondText(
116
+ text = " not healthy" ,
117
+ contentType = ContentType .Text .Plain ,
118
+ status = HttpStatusCode .InternalServerError ,
119
+ )
115
120
}
116
121
}
117
122
get<Paths .getHeaders> {
@@ -283,7 +288,7 @@ class KeyValueLikeModelServer(val repositoriesManager: RepositoriesManager) {
283
288
return result
284
289
}
285
290
286
- protected fun CallContext.putEntries (newEntries : Map <String , String ?>) {
291
+ protected suspend fun CallContext.putEntries (newEntries : Map <String , String ?>) {
287
292
val referencedKeys: MutableSet <String > = HashSet ()
288
293
for ((key, value) in newEntries) {
289
294
checkKeyPermission(key, EPermissionType .WRITE )
@@ -316,18 +321,23 @@ class KeyValueLikeModelServer(val repositoriesManager: RepositoriesManager) {
316
321
HashUtil .isSha256(key) -> {
317
322
hashedObjects[key] = value ? : throw IllegalArgumentException (" No value provided for $key " )
318
323
}
324
+
319
325
BranchReference .tryParseBranch(key) != null -> {
320
326
branchChanges[BranchReference .tryParseBranch(key)!! ] = value
321
327
}
328
+
322
329
key.startsWith(PROTECTED_PREFIX ) -> {
323
330
throw NoPermissionException (" Access to keys starting with '$PROTECTED_PREFIX ' is only permitted to the model server itself." )
324
331
}
332
+
325
333
key.startsWith(RepositoriesManager .KEY_PREFIX ) -> {
326
334
throw NoPermissionException (" Access to keys starting with '${RepositoriesManager .KEY_PREFIX } ' is only permitted to the model server itself." )
327
335
}
336
+
328
337
key == RepositoriesManager .LEGACY_SERVER_ID_KEY || key == RepositoriesManager .LEGACY_SERVER_ID_KEY2 -> {
329
338
throw NoPermissionException (" '$key ' is read-only." )
330
339
}
340
+
331
341
else -> {
332
342
userDefinedEntries[key] = value
333
343
}
@@ -336,14 +346,14 @@ class KeyValueLikeModelServer(val repositoriesManager: RepositoriesManager) {
336
346
337
347
HashUtil .checkObjectHashes(hashedObjects)
338
348
339
- repositoriesManager.client.store.runTransaction {
349
+ repositoriesManager.client.store.runTransactionSuspendable {
340
350
storeClient.putAll(hashedObjects)
341
351
storeClient.putAll(userDefinedEntries)
342
352
for ((branch, value) in branchChanges) {
343
353
if (value == null ) {
344
- repositoriesManager.removeBranches (branch.repositoryId, setOf (branch.branchName))
354
+ repositoriesManager.removeBranchesBlocking (branch.repositoryId, setOf (branch.branchName))
345
355
} else {
346
- repositoriesManager.mergeChanges (branch, value)
356
+ repositoriesManager.mergeChangesBlocking (branch, value)
347
357
}
348
358
}
349
359
}
@@ -365,7 +375,10 @@ class KeyValueLikeModelServer(val repositoriesManager: RepositoriesManager) {
365
375
if (key.startsWith(RepositoriesManager .KEY_PREFIX )) {
366
376
throw NoPermissionException (" Access to keys starting with '${RepositoriesManager .KEY_PREFIX } ' is only permitted to the model server itself." )
367
377
}
368
- if ((key == RepositoriesManager .LEGACY_SERVER_ID_KEY || key == RepositoriesManager .LEGACY_SERVER_ID_KEY2 ) && type.includes(EPermissionType .WRITE )) {
378
+ if ((key == RepositoriesManager .LEGACY_SERVER_ID_KEY || key == RepositoriesManager .LEGACY_SERVER_ID_KEY2 ) && type.includes(
379
+ EPermissionType .WRITE ,
380
+ )
381
+ ) {
369
382
throw NoPermissionException (" '$key ' is read-only." )
370
383
}
371
384
if (HashUtil .isSha256(key)) {
0 commit comments