Message format rework WIP

This commit is contained in:
Alexander Nozik 2020-12-01 10:33:17 +03:00
parent 356f3e15a6
commit 92ab801967
7 changed files with 124 additions and 74 deletions

View File

@ -1,7 +1,11 @@
package hep.dataforge.control.controllers
import hep.dataforge.control.api.*
import hep.dataforge.control.controllers.DeviceMessage.Companion.PROPERTY_CHANGED_ACTION
import hep.dataforge.control.messages.DeviceMessage
import hep.dataforge.control.messages.DeviceMessage.Companion.PROPERTY_CHANGED_ACTION
import hep.dataforge.control.messages.respondsTo
import hep.dataforge.control.messages.toEnvelope
import hep.dataforge.control.messages.toMeta
import hep.dataforge.io.Consumer
import hep.dataforge.io.Envelope
import hep.dataforge.io.Responder
@ -85,7 +89,7 @@ public class DeviceController(
} else error("Device does not support binary response")
}
} catch (ex: Exception) {
DeviceMessage.fail(ex).toEnvelope()
DeviceMessage.error(ex).toEnvelope()
}
}
@ -145,7 +149,7 @@ public class DeviceController(
value = value
)
} catch (ex: Exception) {
DeviceMessage.fail(ex, request.action).respondsTo(request)
DeviceMessage.error(ex, request.action).respondsTo(request)
}
}
}
@ -157,6 +161,6 @@ public suspend fun DeviceHub.respondMessage(request: DeviceMessage): DeviceMessa
val device = this[targetName] ?: error("The device with name $targetName not found in $this")
DeviceController.respondMessage(device, targetName.toString(), request)
} catch (ex: Exception) {
DeviceMessage.fail(ex, request.action).respondsTo(request)
DeviceMessage.error(ex, request.action).respondsTo(request)
}
}

View File

@ -1,61 +0,0 @@
package hep.dataforge.control.controllers
import hep.dataforge.io.SimpleEnvelope
import hep.dataforge.meta.*
import hep.dataforge.names.Name
import hep.dataforge.names.asName
import kotlinx.serialization.Serializable
import kotlinx.serialization.json.Json
import kotlinx.serialization.json.decodeFromJsonElement
import kotlinx.serialization.json.encodeToJsonElement
@Serializable
public data class DeviceMessage(
public val action: String,
public val status: String = OK_STATUS,
public val sourceName: String? = null,
public val targetName: String? = null,
public val comment: String? = null,
public val key: String? = null,
public val value: MetaItem<*>? = null,
) {
public companion object {
public val SOURCE_KEY: Name = DeviceMessage::sourceName.name.asName()
public val TARGET_KEY: Name = DeviceMessage::targetName.name.asName()
public val MESSAGE_ACTION_KEY: Name = DeviceMessage::action.name.asName()
public val MESSAGE_KEY_KEY: Name = DeviceMessage::key.name.asName()
public val MESSAGE_VALUE_KEY: Name = DeviceMessage::value.name.asName()
public const val OK_STATUS: String = "OK"
public const val FAIL_STATUS: String = "FAIL"
public const val PROPERTY_CHANGED_ACTION: String = "event.propertyChanged"
private fun Throwable.toMeta(): Meta = Meta {
"type" put this::class.simpleName
"message" put message
"trace" put stackTraceToString()
}
public fun fail(
cause: Throwable,
action: String = "undefined",
): DeviceMessage = DeviceMessage(
action = action,
status = FAIL_STATUS,
value = cause.toMeta().asMetaItem()
)
public fun fromMeta(meta: Meta): DeviceMessage = Json.decodeFromJsonElement(meta.toJson())
}
}
public fun DeviceMessage.ok(): DeviceMessage =
copy(status = DeviceMessage.OK_STATUS)
public fun DeviceMessage.respondsTo(request: DeviceMessage): DeviceMessage =
copy(sourceName = request.targetName, targetName = request.sourceName)
public fun DeviceMessage.toMeta(): JsonMeta = Json.encodeToJsonElement(this).toMetaItem().node!!
public fun DeviceMessage.toEnvelope(): SimpleEnvelope = SimpleEnvelope(toMeta(), null)

View File

@ -1,8 +1,9 @@
package hep.dataforge.control.controllers
import hep.dataforge.control.api.DeviceHub
import hep.dataforge.control.api.DeviceListener
import hep.dataforge.control.api.get
import hep.dataforge.control.api.*
import hep.dataforge.control.messages.DeviceMessage
import hep.dataforge.control.messages.respondsTo
import hep.dataforge.control.messages.toEnvelope
import hep.dataforge.io.Consumer
import hep.dataforge.io.Envelope
import hep.dataforge.io.Responder
@ -67,7 +68,7 @@ public class HubController(
val device = hub[targetName] ?: error("The device with name $targetName not found in $hub")
DeviceController.respondMessage(device, targetName.toString(), message)
} catch (ex: Exception) {
DeviceMessage.fail(ex, message.action).respondsTo(message)
DeviceMessage.error(ex, message.action).respondsTo(message)
}
override suspend fun respond(request: Envelope): Envelope = try {
@ -79,7 +80,7 @@ public class HubController(
DeviceController.respond(device, targetName.toString(), request)
}
} catch (ex: Exception) {
DeviceMessage.fail(ex).toEnvelope()
DeviceMessage.error(ex).toEnvelope()
}
override fun consume(message: Envelope) {

View File

@ -0,0 +1,106 @@
package hep.dataforge.control.messages
import hep.dataforge.io.SimpleEnvelope
import hep.dataforge.meta.*
import hep.dataforge.names.Name
import hep.dataforge.names.asName
import kotlinx.serialization.SerialName
import kotlinx.serialization.Serializable
import kotlinx.serialization.json.Json
import kotlinx.serialization.json.decodeFromJsonElement
import kotlinx.serialization.json.encodeToJsonElement
@Serializable
public sealed class DeviceMessage{
public abstract val sourceName: String?
public abstract val targetName: String?
public abstract val comment: String?
public companion object {
public val SOURCE_KEY: Name = DeviceMessage::sourceName.name.asName()
public val TARGET_KEY: Name = DeviceMessage::targetName.name.asName()
public val MESSAGE_ACTION_KEY: Name = DeviceMessage::action.name.asName()
public val MESSAGE_KEY_KEY: Name = DeviceMessage::key.name.asName()
public val MESSAGE_VALUE_KEY: Name = DeviceMessage::value.name.asName()
public const val OK_STATUS: String = "OK"
public const val FAIL_STATUS: String = "FAIL"
public const val PROPERTY_CHANGED_ACTION: String = "event.propertyChanged"
public fun error(
cause: Throwable,
): DeviceErrorMessage = DeviceErrorMessage(
errorMessage = cause.message,
errorType = cause::class.simpleName,
errorStackTrace = cause.stackTraceToString()
)
public fun fromMeta(meta: Meta): DeviceMessage = Json.decodeFromJsonElement(meta.toJson())
}
}
@Serializable
@SerialName("property.changed")
public data class PropertyChangedMessage(
public val key: String,
public val value: MetaItem<*>?,
override val sourceName: String? = null,
override val targetName: String? = null,
override val comment: String? = null,
) : DeviceMessage()
@Serializable
@SerialName("property.set")
public data class PropertySetMessage(
public val key: String,
public val value: MetaItem<*>,
override val sourceName: String? = null,
override val targetName: String? = null,
override val comment: String? = null,
) : DeviceMessage()
@Serializable
@SerialName("property.read")
public data class PropertyReadMessage(
public val key: String,
override val sourceName: String? = null,
override val targetName: String? = null,
override val comment: String? = null,
) : DeviceMessage()
@Serializable
@SerialName("action.execute")
public data class ActionExecuteMessage(
public val action: String,
public val argument: MetaItem<*>?,
override val sourceName: String? = null,
override val targetName: String? = null,
override val comment: String? = null,
) : DeviceMessage()
@Serializable
@SerialName("action.result")
public data class ActionResultMessage(
public val action: String,
public val result: MetaItem<*>?,
override val sourceName: String? = null,
override val targetName: String? = null,
override val comment: String? = null,
) : DeviceMessage()
@Serializable
@SerialName("error")
public data class DeviceErrorMessage(
public val errorMessage: String?,
public val errorType: String? = null,
public val errorStackTrace: String? = null,
override val sourceName: String? = null,
override val targetName: String? = null,
override val comment: String? = null,
) : DeviceMessage()
public fun DeviceMessage.toMeta(): JsonMeta = Json.encodeToJsonElement(this).toMetaItem().node!!
public fun DeviceMessage.toEnvelope(): SimpleEnvelope = SimpleEnvelope(toMeta(), null)

View File

@ -1,7 +1,7 @@
package hep.dataforge.control.server
import hep.dataforge.control.controllers.DeviceMessage
import hep.dataforge.control.controllers.toMeta
import hep.dataforge.control.messages.DeviceMessage
import hep.dataforge.control.messages.toMeta
import hep.dataforge.io.*
import hep.dataforge.meta.MetaSerializer
import io.ktor.application.ApplicationCall

View File

@ -7,8 +7,8 @@ import hep.dataforge.control.api.get
import hep.dataforge.control.controllers.DeviceController.Companion.GET_PROPERTY_ACTION
import hep.dataforge.control.controllers.DeviceController.Companion.SET_PROPERTY_ACTION
import hep.dataforge.control.controllers.DeviceManager
import hep.dataforge.control.controllers.DeviceMessage
import hep.dataforge.control.controllers.respondMessage
import hep.dataforge.control.messages.DeviceMessage
import hep.dataforge.meta.toJson
import hep.dataforge.meta.toMeta
import hep.dataforge.meta.toMetaItem

View File

@ -1,8 +1,8 @@
package hep.dataforge.control.client
import hep.dataforge.control.controllers.DeviceManager
import hep.dataforge.control.controllers.DeviceMessage
import hep.dataforge.control.controllers.respondMessage
import hep.dataforge.control.messages.DeviceMessage
import hep.dataforge.magix.api.MagixEndpoint
import hep.dataforge.magix.api.MagixMessage
import hep.dataforge.magix.api.MagixProcessor