From 85f6b81334f33f854f210da26f469ff2ed461252 Mon Sep 17 00:00:00 2001 From: Alexander Nozik Date: Sat, 20 Nov 2021 13:13:32 +0300 Subject: [PATCH] Architecture rework --- .../controls/controllers/deviceMessages.kt | 2 ++ controls-magix-client/build.gradle.kts | 6 ---- .../mipt/npm/controls/client/xodusDfMagix.kt | 36 ++++++++----------- controls-xodus/build.gradle.kts | 7 ++-- .../ru/mipt/npm/controls/xodus/converters.kt | 16 ++++++++- .../ru/mipt/npm/controls/xodus/device.kt | 21 +++++++++++ demo/car/build.gradle.kts | 1 + .../npm/controls/demo/car/MagixVirtualCar.kt | 3 +- .../controls/demo/car/VirtualCarController.kt | 15 ++++---- 9 files changed, 66 insertions(+), 41 deletions(-) create mode 100644 controls-xodus/src/main/kotlin/ru/mipt/npm/controls/xodus/device.kt diff --git a/controls-core/src/commonMain/kotlin/ru/mipt/npm/controls/controllers/deviceMessages.kt b/controls-core/src/commonMain/kotlin/ru/mipt/npm/controls/controllers/deviceMessages.kt index 5158961..71d8cf9 100644 --- a/controls-core/src/commonMain/kotlin/ru/mipt/npm/controls/controllers/deviceMessages.kt +++ b/controls-core/src/commonMain/kotlin/ru/mipt/npm/controls/controllers/deviceMessages.kt @@ -95,6 +95,8 @@ public suspend fun DeviceHub.respondHubMessage(request: DeviceMessage): DeviceMe * Collect all messages from given [DeviceHub], applying proper relative names */ public fun DeviceHub.hubMessageFlow(scope: CoroutineScope): Flow { + + //TODO could we avoid using downstream scope? val outbox = MutableSharedFlow() if (this is Device) { messageFlow.onEach { diff --git a/controls-magix-client/build.gradle.kts b/controls-magix-client/build.gradle.kts index 6acc75f..7941c2e 100644 --- a/controls-magix-client/build.gradle.kts +++ b/controls-magix-client/build.gradle.kts @@ -17,11 +17,5 @@ kotlin { implementation(project(":controls-core")) } } - jvmMain { - dependencies { - implementation("org.jetbrains.xodus:xodus-openAPI:1.3.232") - implementation(project(":controls-xodus")) - } - } } } diff --git a/controls-magix-client/src/jvmMain/kotlin/ru/mipt/npm/controls/client/xodusDfMagix.kt b/controls-magix-client/src/jvmMain/kotlin/ru/mipt/npm/controls/client/xodusDfMagix.kt index 4a8cdc4..f06cd55 100644 --- a/controls-magix-client/src/jvmMain/kotlin/ru/mipt/npm/controls/client/xodusDfMagix.kt +++ b/controls-magix-client/src/jvmMain/kotlin/ru/mipt/npm/controls/client/xodusDfMagix.kt @@ -1,24 +1,16 @@ package ru.mipt.npm.controls.client -import jetbrains.exodus.entitystore.PersistentEntityStore -import kotlinx.coroutines.Job -import ru.mipt.npm.controls.api.DeviceMessage -import ru.mipt.npm.controls.api.PropertyChangedMessage -import ru.mipt.npm.controls.controllers.DeviceManager -import ru.mipt.npm.controls.xodus.toEntity -import ru.mipt.npm.magix.api.MagixEndpoint - -/** - * Communicate with server in [Magix format](https://github.com/waltz-controls/rfc/tree/master/1) and dump messages at xodus entity store - */ -public fun DeviceManager.connectToMagix( - endpoint: MagixEndpoint, - endpointID: String = DATAFORGE_MAGIX_FORMAT, - entityStore: PersistentEntityStore -): Job = connectToMagix(endpoint, endpointID) { message -> - if (message.payload is PropertyChangedMessage) { - entityStore.executeInTransaction { - message.toEntity(it) - } - } -} +///** +// * Communicate with server in [Magix format](https://github.com/waltz-controls/rfc/tree/master/1) and dump messages at xodus entity store +// */ +//public fun DeviceManager.connectToMagix( +// endpoint: MagixEndpoint, +// endpointID: String = DATAFORGE_MAGIX_FORMAT, +// entityStore: PersistentEntityStore +//): Job = connectToMagix(endpoint, endpointID) { message -> +// if (message.payload is PropertyChangedMessage) { +// entityStore.executeInTransaction { +// message.toEntity(it) +// } +// } +//} diff --git a/controls-xodus/build.gradle.kts b/controls-xodus/build.gradle.kts index e6dc62b..bf1e98d 100644 --- a/controls-xodus/build.gradle.kts +++ b/controls-xodus/build.gradle.kts @@ -3,11 +3,12 @@ plugins { `maven-publish` } +val xodusVersion = "1.3.232" dependencies { implementation(projects.controlsCore) implementation(projects.magix.magixApi) - implementation("org.jetbrains.xodus:xodus-entity-store:1.3.232") - implementation("org.jetbrains.xodus:xodus-environment:1.3.232") - implementation("org.jetbrains.xodus:xodus-vfs:1.3.232") + implementation("org.jetbrains.xodus:xodus-entity-store:$xodusVersion") + implementation("org.jetbrains.xodus:xodus-environment:$xodusVersion") + implementation("org.jetbrains.xodus:xodus-vfs:$xodusVersion") } \ No newline at end of file diff --git a/controls-xodus/src/main/kotlin/ru/mipt/npm/controls/xodus/converters.kt b/controls-xodus/src/main/kotlin/ru/mipt/npm/controls/xodus/converters.kt index 83b3035..76bdb63 100644 --- a/controls-xodus/src/main/kotlin/ru/mipt/npm/controls/xodus/converters.kt +++ b/controls-xodus/src/main/kotlin/ru/mipt/npm/controls/xodus/converters.kt @@ -8,12 +8,26 @@ import kotlinx.serialization.json.JsonElement import ru.mipt.npm.controls.api.PropertyChangedMessage import ru.mipt.npm.magix.api.MagixMessage import space.kscience.dataforge.meta.MetaSerializer +import space.kscience.dataforge.meta.isLeaf import space.kscience.dataforge.names.Name +import space.kscience.dataforge.values.Value +import space.kscience.dataforge.values.ValueType public fun PropertyChangedMessage.toEntity(transaction: StoreTransaction): Entity { val entity = transaction.newEntity("PropertyChangedMessage") entity.setProperty("property", property) - entity.setProperty("value", value.toString()) + if (value.isLeaf) { + val v: Value = value.value ?: TODO() + when(v.type){ + ValueType.NULL -> TODO() + ValueType.LIST -> TODO() + ValueType.NUMBER -> TODO() + ValueType.STRING -> TODO() + ValueType.BOOLEAN -> TODO() + } + } else { + entity.setProperty("value", value.toString()) + } entity.setProperty("sourceDevice", sourceDevice.toString()) targetDevice?.let { entity.setProperty("targetDevice", it.toString()) } comment?.let { entity.setProperty("comment", it) } diff --git a/controls-xodus/src/main/kotlin/ru/mipt/npm/controls/xodus/device.kt b/controls-xodus/src/main/kotlin/ru/mipt/npm/controls/xodus/device.kt new file mode 100644 index 0000000..c4c2d40 --- /dev/null +++ b/controls-xodus/src/main/kotlin/ru/mipt/npm/controls/xodus/device.kt @@ -0,0 +1,21 @@ +package ru.mipt.npm.controls.xodus + +import jetbrains.exodus.entitystore.PersistentEntityStore +import kotlinx.coroutines.Job +import kotlinx.coroutines.flow.launchIn +import kotlinx.coroutines.flow.onEach +import ru.mipt.npm.controls.api.PropertyChangedMessage +import ru.mipt.npm.controls.controllers.DeviceManager +import ru.mipt.npm.controls.controllers.hubMessageFlow + + +public fun DeviceManager.connectXodus( + entityStore: PersistentEntityStore, + //filter: (DeviceMessage) -> Boolean = {it is PropertyChangedMessage} +): Job = hubMessageFlow(context).onEach { message -> + if (message is PropertyChangedMessage) { + entityStore.executeInTransaction { + message.toEntity(it) + } + } +}.launchIn(context) \ No newline at end of file diff --git a/demo/car/build.gradle.kts b/demo/car/build.gradle.kts index c5b3da5..3427645 100644 --- a/demo/car/build.gradle.kts +++ b/demo/car/build.gradle.kts @@ -19,6 +19,7 @@ dependencies { implementation(projects.magix.magixServer) implementation(projects.magix.magixRsocket) implementation(projects.controlsMagixClient) + implementation(projects.controlsXodus) implementation("io.ktor:ktor-client-cio:$ktorVersion") implementation("org.jetbrains.kotlinx:kotlinx-datetime:0.3.1") diff --git a/demo/car/src/main/kotlin/ru/mipt/npm/controls/demo/car/MagixVirtualCar.kt b/demo/car/src/main/kotlin/ru/mipt/npm/controls/demo/car/MagixVirtualCar.kt index 3d0c97c..bee2464 100644 --- a/demo/car/src/main/kotlin/ru/mipt/npm/controls/demo/car/MagixVirtualCar.kt +++ b/demo/car/src/main/kotlin/ru/mipt/npm/controls/demo/car/MagixVirtualCar.kt @@ -14,8 +14,7 @@ import space.kscience.dataforge.meta.string import space.kscience.dataforge.names.Name import kotlin.time.ExperimentalTime -class MagixVirtualCar(context: Context, meta: Meta) - : VirtualCar(context, meta) { +class MagixVirtualCar(context: Context, meta: Meta) : VirtualCar(context, meta) { private suspend fun MagixEndpoint.startMagixVirtualCarUpdate() { launch { diff --git a/demo/car/src/main/kotlin/ru/mipt/npm/controls/demo/car/VirtualCarController.kt b/demo/car/src/main/kotlin/ru/mipt/npm/controls/demo/car/VirtualCarController.kt index a8f5e54..90489c3 100644 --- a/demo/car/src/main/kotlin/ru/mipt/npm/controls/demo/car/VirtualCarController.kt +++ b/demo/car/src/main/kotlin/ru/mipt/npm/controls/demo/car/VirtualCarController.kt @@ -1,20 +1,21 @@ package ru.mipt.npm.controls.demo.car -import io.ktor.server.engine.* +import io.ktor.server.engine.ApplicationEngine import javafx.beans.property.DoubleProperty import javafx.scene.Parent import javafx.scene.control.TextField import javafx.scene.layout.Priority import javafx.stage.Stage import jetbrains.exodus.entitystore.PersistentEntityStore -import jetbrains.exodus.entitystore.PersistentEntityStoreImpl import jetbrains.exodus.entitystore.PersistentEntityStores +import kotlinx.coroutines.Job import kotlinx.coroutines.launch import ru.mipt.npm.controls.api.DeviceMessage import ru.mipt.npm.controls.client.connectToMagix import ru.mipt.npm.controls.controllers.DeviceManager import ru.mipt.npm.controls.controllers.install import ru.mipt.npm.controls.demo.car.IVirtualCar.Companion.acceleration +import ru.mipt.npm.controls.xodus.connectXodus import ru.mipt.npm.magix.api.MagixEndpoint import ru.mipt.npm.magix.rsocket.rSocketWithTcp import ru.mipt.npm.magix.server.startMagixServer @@ -27,6 +28,7 @@ class VirtualCarController : Controller(), ContextAware { var magixVirtualCar: MagixVirtualCar? = null var magixServer: ApplicationEngine? = null var entityStore: PersistentEntityStore? = null + var storageJob: Job? =null override val context = Context("demoDevice") { plugin(DeviceManager) @@ -37,17 +39,16 @@ class VirtualCarController : Controller(), ContextAware { fun init() { context.launch { virtualCar = deviceManager.install("virtual-car", VirtualCar) + //starting magix event loop magixServer = startMagixServer(enableRawRSocket = true, enableZmq = true) magixVirtualCar = deviceManager.install("magix-virtual-car", MagixVirtualCar) entityStore = PersistentEntityStores.newInstance("/home/marvel1337/2021/SCADA/.messages") + //connect to entity store + storageJob = deviceManager.connectXodus(entityStore as PersistentEntityStore) //Launch device client and connect it to the server val deviceEndpoint = MagixEndpoint.rSocketWithTcp("localhost", DeviceMessage.serializer()) - if (entityStore != null) { - deviceManager.connectToMagix(deviceEndpoint, entityStore = entityStore as PersistentEntityStoreImpl) - } else { - deviceManager.connectToMagix(deviceEndpoint) - } + deviceManager.connectToMagix(deviceEndpoint) } }