From 197675fc1556755025333310a3c6e5ae44b3abe7 Mon Sep 17 00:00:00 2001 From: Alexander Nozik Date: Sat, 15 Apr 2023 20:00:47 +0300 Subject: [PATCH] Add MQTT prototype (not tested) --- controls-core/build.gradle.kts | 2 +- .../controls-xodus/build.gradle.kts | 2 +- demo/all-things/build.gradle.kts | 6 +- demo/car/build.gradle.kts | 5 +- .../controls/demo/car/VirtualCarController.kt | 2 +- demo/echo/build.gradle.kts | 4 +- demo/magix-demo/build.gradle.kts | 2 +- .../pimotionmaster/PiMotionMasterApp.kt | 4 +- gradle.properties | 2 +- gradle/wrapper/gradle-wrapper.properties | 2 +- magix/magix-mqtt/build.gradle.kts | 18 +++++ .../ksceince/magix/mqtt/MqttMagixEndpoint.kt | 69 +++++++++++++++++++ .../magix-storage-xodus/build.gradle.kts | 2 +- settings.gradle.kts | 4 +- 14 files changed, 110 insertions(+), 14 deletions(-) create mode 100644 magix/magix-mqtt/build.gradle.kts create mode 100644 magix/magix-mqtt/src/main/kotlin/space/ksceince/magix/mqtt/MqttMagixEndpoint.kt diff --git a/controls-core/build.gradle.kts b/controls-core/build.gradle.kts index 8585f17..abceb3d 100644 --- a/controls-core/build.gradle.kts +++ b/controls-core/build.gradle.kts @@ -15,6 +15,6 @@ kscience { } dependencies { api("space.kscience:dataforge-io:$dataforgeVersion") - api(npmlibs.kotlinx.datetime) + api(spclibs.kotlinx.datetime) } } diff --git a/controls-storage/controls-xodus/build.gradle.kts b/controls-storage/controls-xodus/build.gradle.kts index b745b0b..635f8e3 100644 --- a/controls-storage/controls-xodus/build.gradle.kts +++ b/controls-storage/controls-xodus/build.gradle.kts @@ -11,7 +11,7 @@ dependencies { // implementation("org.jetbrains.xodus:xodus-environment:$xodusVersion") // implementation("org.jetbrains.xodus:xodus-vfs:$xodusVersion") - testImplementation(npmlibs.kotlinx.coroutines.test) + testImplementation(spclibs.kotlinx.coroutines.test) } readme{ diff --git a/demo/all-things/build.gradle.kts b/demo/all-things/build.gradle.kts index 1f86f1c..b135253 100644 --- a/demo/all-things/build.gradle.kts +++ b/demo/all-things/build.gradle.kts @@ -29,9 +29,13 @@ dependencies { implementation("ch.qos.logback:logback-classic:1.2.11") } +kotlin{ + jvmToolchain(11) +} + + tasks.withType().configureEach { kotlinOptions { - jvmTarget = "11" freeCompilerArgs = freeCompilerArgs + listOf("-Xjvm-default=all", "-Xopt-in=kotlin.RequiresOptIn") } } diff --git a/demo/car/build.gradle.kts b/demo/car/build.gradle.kts index 27e5776..3c943dd 100644 --- a/demo/car/build.gradle.kts +++ b/demo/car/build.gradle.kts @@ -35,9 +35,12 @@ dependencies { // implementation("org.litote.kmongo:kmongo-coroutine-serialization:4.4.0") } +kotlin{ + jvmToolchain(11) +} + tasks.withType().configureEach { kotlinOptions { - jvmTarget = "11" freeCompilerArgs = freeCompilerArgs + listOf("-Xjvm-default=all", "-Xopt-in=kotlin.RequiresOptIn") } } diff --git a/demo/car/src/main/kotlin/space/kscience/controls/demo/car/VirtualCarController.kt b/demo/car/src/main/kotlin/space/kscience/controls/demo/car/VirtualCarController.kt index 1f98ef7..bde7e6b 100644 --- a/demo/car/src/main/kotlin/space/kscience/controls/demo/car/VirtualCarController.kt +++ b/demo/car/src/main/kotlin/space/kscience/controls/demo/car/VirtualCarController.kt @@ -38,7 +38,7 @@ class VirtualCarController : Controller(), ContextAware { plugin(DeviceManager) } - private val deviceManager = context.fetch(DeviceManager, Meta { + private val deviceManager = context.request(DeviceManager, Meta { "xodusConfig" put { "entityStorePath" put deviceEntityStorePath.toString() } diff --git a/demo/echo/build.gradle.kts b/demo/echo/build.gradle.kts index 47ac2af..5563ba3 100644 --- a/demo/echo/build.gradle.kts +++ b/demo/echo/build.gradle.kts @@ -19,10 +19,12 @@ dependencies { implementation("ch.qos.logback:logback-classic:1.2.11") } +kotlin{ + jvmToolchain(11) +} tasks.withType().configureEach { kotlinOptions { - jvmTarget = "11" freeCompilerArgs = freeCompilerArgs + listOf("-Xjvm-default=all", "-Xopt-in=kotlin.RequiresOptIn") } } diff --git a/demo/magix-demo/build.gradle.kts b/demo/magix-demo/build.gradle.kts index 411b9c4..babf240 100644 --- a/demo/magix-demo/build.gradle.kts +++ b/demo/magix-demo/build.gradle.kts @@ -8,7 +8,7 @@ dependencies{ implementation(projects.magix.magixServer) implementation(projects.magix.magixZmq) implementation(projects.magix.magixRsocket) - implementation("ch.qos.logback:logback-classic:1.2.3") + implementation(spclibs.logback.classic) } kotlin{ diff --git a/demo/motors/src/main/kotlin/ru/mipt/npm/devices/pimotionmaster/PiMotionMasterApp.kt b/demo/motors/src/main/kotlin/ru/mipt/npm/devices/pimotionmaster/PiMotionMasterApp.kt index 45fe757..4ead06d 100644 --- a/demo/motors/src/main/kotlin/ru/mipt/npm/devices/pimotionmaster/PiMotionMasterApp.kt +++ b/demo/motors/src/main/kotlin/ru/mipt/npm/devices/pimotionmaster/PiMotionMasterApp.kt @@ -17,7 +17,7 @@ import ru.mipt.npm.devices.pimotionmaster.PiMotionMasterDevice.Axis.Companion.po import space.kscience.controls.manager.DeviceManager import space.kscience.controls.manager.installing import space.kscience.dataforge.context.Context -import space.kscience.dataforge.context.fetch +import space.kscience.dataforge.context.request import tornadofx.* class PiMotionMasterApp : App(PiMotionMasterView::class) @@ -29,7 +29,7 @@ class PiMotionMasterController : Controller() { } //initialize deviceManager plugin - val deviceManager: DeviceManager = context.fetch(DeviceManager) + val deviceManager: DeviceManager = context.request(DeviceManager) // install device val motionMaster: PiMotionMasterDevice by deviceManager.installing(PiMotionMasterDevice) diff --git a/gradle.properties b/gradle.properties index d422be3..3ba1c64 100644 --- a/gradle.properties +++ b/gradle.properties @@ -7,4 +7,4 @@ org.gradle.parallel=true publishing.github=false publishing.sonatype=false -toolsVersion=0.14.3-kotlin-1.8.10 \ No newline at end of file +toolsVersion=0.14.6-kotlin-1.8.20 \ No newline at end of file diff --git a/gradle/wrapper/gradle-wrapper.properties b/gradle/wrapper/gradle-wrapper.properties index 070cb70..59bc51a 100644 --- a/gradle/wrapper/gradle-wrapper.properties +++ b/gradle/wrapper/gradle-wrapper.properties @@ -1,5 +1,5 @@ distributionBase=GRADLE_USER_HOME distributionPath=wrapper/dists -distributionUrl=https\://services.gradle.org/distributions/gradle-7.6-bin.zip +distributionUrl=https\://services.gradle.org/distributions/gradle-8.1-bin.zip zipStoreBase=GRADLE_USER_HOME zipStorePath=wrapper/dists diff --git a/magix/magix-mqtt/build.gradle.kts b/magix/magix-mqtt/build.gradle.kts new file mode 100644 index 0000000..e7037e6 --- /dev/null +++ b/magix/magix-mqtt/build.gradle.kts @@ -0,0 +1,18 @@ +plugins { + id("space.kscience.gradle.jvm") + `maven-publish` +} + +description = """ + MQTT client magix endpoint +""".trimIndent() + +dependencies { + api(projects.magix.magixApi) + implementation("com.hivemq:hivemq-mqtt-client:1.3.1") + implementation(spclibs.kotlinx.coroutines.jdk8) +} + +readme{ + maturity = space.kscience.gradle.Maturity.PROTOTYPE +} diff --git a/magix/magix-mqtt/src/main/kotlin/space/ksceince/magix/mqtt/MqttMagixEndpoint.kt b/magix/magix-mqtt/src/main/kotlin/space/ksceince/magix/mqtt/MqttMagixEndpoint.kt new file mode 100644 index 0000000..c9ac7f7 --- /dev/null +++ b/magix/magix-mqtt/src/main/kotlin/space/ksceince/magix/mqtt/MqttMagixEndpoint.kt @@ -0,0 +1,69 @@ +package space.ksceince.magix.mqtt + +import com.hivemq.client.mqtt.MqttClient +import com.hivemq.client.mqtt.datatypes.MqttQos +import com.hivemq.client.mqtt.mqtt5.Mqtt5AsyncClient +import kotlinx.coroutines.channels.awaitClose +import kotlinx.coroutines.channels.trySendBlocking +import kotlinx.coroutines.flow.Flow +import kotlinx.coroutines.flow.callbackFlow +import kotlinx.coroutines.future.await +import space.kscience.magix.api.MagixEndpoint +import space.kscience.magix.api.MagixMessage +import space.kscience.magix.api.MagixMessageFilter +import java.util.* + + +public class MqttMagixEndpoint( + serverHost: String, + clientId: String = UUID.randomUUID().toString(), + public val topic: String = DEFAULT_MAGIX_TOPIC_NAME, + public val qos: MqttQos = MqttQos.AT_LEAST_ONCE, +) : MagixEndpoint, AutoCloseable { + + private val client: Mqtt5AsyncClient by lazy { + MqttClient.builder() + .identifier(clientId) + .serverHost(serverHost) + .useMqttVersion5() + .buildAsync() + } + + private val connection by lazy { + client.connect() + } + + override fun subscribe(filter: MagixMessageFilter): Flow = callbackFlow { + connection.await() + client.subscribeWith() + .topicFilter(topic) + .qos(qos) + .callback { published -> + val message = MagixEndpoint.magixJson.decodeFromString( + MagixMessage.serializer(), + published.payloadAsBytes.decodeToString() + ) + trySendBlocking(message) + } + .send() + + awaitClose { + client.disconnect() + } + } + + override suspend fun broadcast(message: MagixMessage) { + connection.await() + client.publishWith().topic(topic).qos(qos).payload( + MagixEndpoint.magixJson.encodeToString(MagixMessage.serializer(), message).encodeToByteArray() + ).send() + } + + override fun close() { + client.disconnect() + } + + public companion object { + public const val DEFAULT_MAGIX_TOPIC_NAME: String = "magix" + } +} \ No newline at end of file diff --git a/magix/magix-storage/magix-storage-xodus/build.gradle.kts b/magix/magix-storage/magix-storage-xodus/build.gradle.kts index 63a1b44..8869867 100644 --- a/magix/magix-storage/magix-storage-xodus/build.gradle.kts +++ b/magix/magix-storage/magix-storage-xodus/build.gradle.kts @@ -13,7 +13,7 @@ dependencies { api(projects.magix.magixApi) implementation("org.jetbrains.xodus:xodus-entity-store:$xodusVersion") - testImplementation(npmlibs.kotlinx.coroutines.test) + testImplementation(spclibs.kotlinx.coroutines.test) } readme{ diff --git a/settings.gradle.kts b/settings.gradle.kts index a8f250b..c66ec81 100644 --- a/settings.gradle.kts +++ b/settings.gradle.kts @@ -1,7 +1,6 @@ rootProject.name = "controls-kt" enableFeaturePreview("TYPESAFE_PROJECT_ACCESSORS") -enableFeaturePreview("VERSION_CATALOGS") pluginManagement { @@ -34,7 +33,7 @@ dependencyResolutionManagement { } versionCatalogs { - create("npmlibs") { + create("spclibs") { from("space.kscience:version-catalog:$toolsVersion") } } @@ -56,6 +55,7 @@ include( ":magix:magix-java-client", ":magix:magix-zmq", ":magix:magix-rabbit", + ":magix:magix-mqtt", // ":magix:magix-storage", ":magix:magix-storage:magix-storage-xodus",