Skip to content

Commit 2bc95b8

Browse files
committed
feat(light-model-client): support for remote execution of ModelQL on nodes returned by the client
1 parent 4eb8ccb commit 2bc95b8

File tree

3 files changed

+79
-17
lines changed

3 files changed

+79
-17
lines changed

light-model-client/build.gradle.kts

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -23,10 +23,15 @@ kotlin {
2323
implementation(project(":model-api"))
2424
implementation(project(":model-api-gen-runtime"))
2525
implementation(project(":model-server-api"))
26+
implementation(project(":modelql-core"))
27+
implementation(project(":modelql-untyped"))
28+
implementation(project(":modelql-client"))
29+
2630
implementation(libs.ktor.client.websockets)
2731
implementation(libs.kotlin.stdlib.common)
2832
implementation(libs.kotlin.logging)
2933
implementation(libs.kotlin.coroutines.core)
34+
implementation(libs.kotlin.serialization.json)
3035

3136
// implementation("io.ktor:ktor-client-core:$ktorVersion")
3237
// implementation("io.ktor:ktor-client-cio:$ktorVersion")
@@ -50,10 +55,12 @@ kotlin {
5055
val jvmTest by getting {
5156
dependencies {
5257
implementation(kotlin("test"))
53-
implementation(kotlin("test-junit"))
5458

55-
implementation(project(":model-server"))
5659
implementation(project(":authorization"))
60+
// implementation(project(":model-client"))
61+
implementation(project(":model-server"))
62+
implementation(project(":model-server-lib"))
63+
5764
implementation(libs.ktor.server.core)
5865
implementation(libs.ktor.server.cors)
5966
implementation(libs.ktor.server.netty)

light-model-client/src/commonMain/kotlin/org/modelix/client/light/LightModelClient.kt

Lines changed: 61 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,52 @@
11
package org.modelix.client.light
22

3-
import io.ktor.client.*
4-
import io.ktor.client.engine.*
5-
import io.ktor.client.plugins.websocket.*
3+
import io.ktor.client.HttpClient
4+
import io.ktor.client.engine.HttpClientEngine
5+
import io.ktor.client.engine.HttpClientEngineFactory
6+
import io.ktor.client.plugins.websocket.WebSockets
67
import kotlinx.coroutines.delay
7-
import org.modelix.model.api.*
8-
import org.modelix.model.area.*
9-
import org.modelix.model.server.api.*
8+
import org.modelix.model.api.ConceptReference
9+
import org.modelix.model.api.IBranch
10+
import org.modelix.model.api.IConcept
11+
import org.modelix.model.api.IConceptReference
12+
import org.modelix.model.api.INode
13+
import org.modelix.model.api.INodeEx
14+
import org.modelix.model.api.INodeReference
15+
import org.modelix.model.api.INodeReferenceSerializer
16+
import org.modelix.model.api.INodeReferenceSerializerEx
17+
import org.modelix.model.api.NodeReferenceById
18+
import org.modelix.model.api.SerializedNodeReference
19+
import org.modelix.model.api.getAncestors
20+
import org.modelix.model.api.resolve
21+
import org.modelix.model.area.IArea
22+
import org.modelix.model.area.IAreaChangeEvent
23+
import org.modelix.model.area.IAreaChangeList
24+
import org.modelix.model.area.IAreaListener
25+
import org.modelix.model.area.IAreaReference
26+
import org.modelix.model.server.api.AddNewChildNodeOpData
27+
import org.modelix.model.server.api.ChangeSetId
28+
import org.modelix.model.server.api.DeleteNodeOpData
29+
import org.modelix.model.server.api.ExceptionData
30+
import org.modelix.model.server.api.MessageFromClient
31+
import org.modelix.model.server.api.MessageFromServer
32+
import org.modelix.model.server.api.ModelQuery
33+
import org.modelix.model.server.api.MoveNodeOpData
34+
import org.modelix.model.server.api.NodeData
35+
import org.modelix.model.server.api.NodeId
36+
import org.modelix.model.server.api.NodeUpdateData
37+
import org.modelix.model.server.api.OperationData
38+
import org.modelix.model.server.api.QueryRootNode
39+
import org.modelix.model.server.api.SetPropertyOpData
40+
import org.modelix.model.server.api.SetReferenceOpData
41+
import org.modelix.model.server.api.VersionData
42+
import org.modelix.model.server.api.merge
43+
import org.modelix.model.server.api.replaceChildren
44+
import org.modelix.model.server.api.replaceContainment
45+
import org.modelix.model.server.api.replaceId
46+
import org.modelix.model.server.api.replaceReferences
47+
import org.modelix.modelql.client.ModelQLClient
48+
import org.modelix.modelql.core.IQueryExecutor
49+
import org.modelix.modelql.untyped.ISupportsModelQL
1050
import kotlin.jvm.JvmStatic
1151
import kotlin.time.Duration
1252
import kotlin.time.Duration.Companion.milliseconds
@@ -18,7 +58,8 @@ class LightModelClient internal constructor(
1858
val connection: IConnection,
1959
private val transactionManager: ITransactionManager,
2060
val autoFilterNonLoadedNodes: Boolean,
21-
val debugName: String = ""
61+
val debugName: String = "",
62+
val modelQLClient: ModelQLClient? = null
2263
) {
2364

2465
private val nodes: MutableMap<NodeId, NodeData> = HashMap()
@@ -324,7 +365,7 @@ class LightModelClient internal constructor(
324365
}
325366
}
326367

327-
inner class NodeAdapter(var nodeId: NodeId) : INodeEx {
368+
inner class NodeAdapter(var nodeId: NodeId) : INodeEx, ISupportsModelQL {
328369
fun getData() = requiresRead { getNodeData(nodeId) }
329370

330371
override fun usesRoleIds(): Boolean = usesRoleIds
@@ -562,6 +603,11 @@ class LightModelClient internal constructor(
562603
override fun toString(): String {
563604
return nodeId
564605
}
606+
607+
override fun createQueryExecutor(): IQueryExecutor<INode> {
608+
val client = modelQLClient ?: throw UnsupportedOperationException("Connection doesn't support ModelQL: $connection")
609+
return client.getNode(SerializedNodeReference(nodeId))
610+
}
565611
}
566612

567613
inner class Area : IArea {
@@ -732,6 +778,7 @@ abstract class LightModelClientBuilder {
732778
private var debugName: String = ""
733779
private var transactionManager: ITransactionManager = ReadWriteLockTransactionManager()
734780
private var autoFilterNonLoadedNodes: Boolean = false
781+
private var modelQLClient: ModelQLClient? = null
735782

736783
protected abstract fun getDefaultEngineFactory(): HttpClientEngineFactory<*>
737784

@@ -749,7 +796,8 @@ abstract class LightModelClientBuilder {
749796
),
750797
transactionManager,
751798
autoFilterNonLoadedNodes = autoFilterNonLoadedNodes,
752-
debugName = debugName
799+
debugName = debugName,
800+
modelQLClient = modelQLClient
753801
)
754802
}
755803
fun autoFilterNonLoadedNodes(value: Boolean = true): LightModelClientBuilder {
@@ -795,6 +843,10 @@ abstract class LightModelClientBuilder {
795843
this.httpEngineFactory = httpEngineFactory
796844
return this
797845
}
846+
fun modelQLClient(c: ModelQLClient): LightModelClientBuilder {
847+
this.modelQLClient = c
848+
return this
849+
}
798850
}
799851

800852
class LightClientNodeReference(val nodeId: NodeId) : INodeReference {

light-model-client/src/commonMain/kotlin/org/modelix/client/light/WebsocketConnection.kt

Lines changed: 9 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -16,18 +16,22 @@
1616

1717
package org.modelix.client.light
1818

19-
import io.ktor.client.*
20-
import io.ktor.client.plugins.websocket.*
21-
import io.ktor.websocket.*
19+
import io.ktor.client.HttpClient
20+
import io.ktor.client.plugins.websocket.webSocket
21+
import io.ktor.websocket.CloseReason
22+
import io.ktor.websocket.Frame
23+
import io.ktor.websocket.WebSocketSession
24+
import io.ktor.websocket.close
25+
import io.ktor.websocket.readText
26+
import io.ktor.websocket.send
2227
import kotlinx.coroutines.CoroutineScope
2328
import kotlinx.coroutines.Dispatchers
24-
import kotlinx.coroutines.GlobalScope
25-
import kotlinx.coroutines.cancel
2629
import kotlinx.coroutines.channels.Channel
2730
import kotlinx.coroutines.channels.ClosedReceiveChannelException
2831
import kotlinx.coroutines.launch
2932
import org.modelix.model.server.api.MessageFromClient
3033
import org.modelix.model.server.api.MessageFromServer
34+
import org.modelix.modelql.client.ModelQLClient
3135

3236
class WebsocketConnection(val httpClient: HttpClient, val url: String) : LightModelClient.IConnection {
3337
val coroutineScope = CoroutineScope(Dispatchers.Default)
@@ -73,5 +77,4 @@ class WebsocketConnection(val httpClient: HttpClient, val url: String) : LightMo
7377
}
7478
}
7579
}
76-
7780
}

0 commit comments

Comments
 (0)