From 57488844ddfbd33ea93d58521252598716cde511 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mark=20Hu=CC=88sers?= Date: Wed, 28 Feb 2024 16:17:43 +0100 Subject: [PATCH 01/20] refactor: Align Terminology of VSS model classes / public API VssProperty -> VssNode close #70 --- .../org/eclipse/kuksa/DataBrokerConnection.kt | 14 ++++---- .../org/eclipse/kuksa/PropertyListener.kt | 6 ++-- .../kuksa/extension/DataPointExtension.kt | 8 ++--- .../VssSpecificationCopyExtension.kt | 16 ++++----- .../extension/VssSpecificationExtension.kt | 4 +-- .../VssPropertyBooleanExtension.kt | 4 +-- .../vssProperty/VssPropertyDoubleExtension.kt | 34 +++++++++---------- .../vssProperty/VssPropertyFloatExtension.kt | 34 +++++++++---------- .../vssProperty/VssPropertyIntExtension.kt | 34 +++++++++---------- .../vssProperty/VssPropertyLongExtension.kt | 34 +++++++++---------- .../org/eclipse/kuksa/model/Property.kt | 2 +- .../subscription/DataBrokerSubscriber.kt | 8 ++--- .../kuksa/vssSpecification/VssDriver.kt | 18 +++++----- .../VssSpecificationCopyTest.kt | 4 +-- .../kuksa/vssSpecification/VssVehicle.kt | 14 ++++---- .../kuksa/vsscore/model/VssSpecification.kt | 18 +++++----- .../eclipse/kuksa/vsscore/model/VssVehicle.kt | 4 +-- .../spec/VssSpecificationSpecModel.kt | 11 +++--- 18 files changed, 133 insertions(+), 134 deletions(-) diff --git a/kuksa-sdk/src/main/kotlin/org/eclipse/kuksa/DataBrokerConnection.kt b/kuksa-sdk/src/main/kotlin/org/eclipse/kuksa/DataBrokerConnection.kt index ee7db7f9..a5b8328e 100644 --- a/kuksa-sdk/src/main/kotlin/org/eclipse/kuksa/DataBrokerConnection.kt +++ b/kuksa-sdk/src/main/kotlin/org/eclipse/kuksa/DataBrokerConnection.kt @@ -37,7 +37,7 @@ import org.eclipse.kuksa.proto.v1.Types import org.eclipse.kuksa.proto.v1.Types.Datapoint import org.eclipse.kuksa.proto.v1.Types.Field import org.eclipse.kuksa.subscription.DataBrokerSubscriber -import org.eclipse.kuksa.vsscore.model.VssProperty +import org.eclipse.kuksa.vsscore.model.VssLeaf import org.eclipse.kuksa.vsscore.model.VssSpecification import org.eclipse.kuksa.vsscore.model.heritage import org.eclipse.kuksa.vsscore.model.vssProperties @@ -112,10 +112,10 @@ class DataBrokerConnection internal constructor( } /** - * Subscribes to the specified [VssSpecification] with the provided [VssSpecificationListener]. Only a [VssProperty] + * Subscribes to the specified [VssSpecification] with the provided [VssSpecificationListener]. Only a [VssLeaf] * can be subscribed because they have an actual value. When provided with any parent [VssSpecification] then this - * [subscribe] method will find all [VssProperty] children and subscribes them instead. Once subscribed the - * application will be notified about any changes to every subscribed [VssProperty]. The [fields] can be used to + * [subscribe] method will find all [VssLeaf] children and subscribes them instead. Once subscribed the + * application will be notified about any changes to every subscribed [VssLeaf]. The [fields] can be used to * subscribe to different information of the [specification]. The default for the [fields] parameter is a list with * a single [Types.Field.FIELD_VALUE] entry. * @@ -210,14 +210,14 @@ class DataBrokerConnection internal constructor( } /** - * Only a [VssProperty] can be updated because they have an actual value. When provided with any parent - * [VssSpecification] then this [update] method will find all [VssProperty] children and updates their corresponding + * Only a [VssLeaf] can be updated because they have an actual value. When provided with any parent + * [VssSpecification] then this [update] method will find all [VssLeaf] children and updates their corresponding * [fields] instead. * Compared to [update] with only one [Property] and [Datapoint], here multiple [SetResponse] will be returned * because a [VssSpecification] may consists of multiple values which may need to be updated. * * @throws DataBrokerException in case the connection to the DataBroker is no longer active - * @throws IllegalArgumentException if the [VssProperty] could not be converted to a [Datapoint]. + * @throws IllegalArgumentException if the [VssLeaf] could not be converted to a [Datapoint]. */ @JvmOverloads suspend fun update( diff --git a/kuksa-sdk/src/main/kotlin/org/eclipse/kuksa/PropertyListener.kt b/kuksa-sdk/src/main/kotlin/org/eclipse/kuksa/PropertyListener.kt index 50f0af6a..617eb786 100644 --- a/kuksa-sdk/src/main/kotlin/org/eclipse/kuksa/PropertyListener.kt +++ b/kuksa-sdk/src/main/kotlin/org/eclipse/kuksa/PropertyListener.kt @@ -24,9 +24,9 @@ import org.eclipse.kuksa.proto.v1.KuksaValV1 import org.eclipse.kuksa.vsscore.model.VssSpecification /** - * The Listener is used to notify about changes to subscribed properties. When registering the listener to - * Vehicle.ADAS.ABS this listener will also be notified about changes of sub-properties e.g. Vehicle.ADAS.ABS.IsEnabled - * or Vehicle.ADAS.ABS.IsEngaged. + * The Listener is used to notify about changes to subscribed [org.eclipse.kuksa.model.Property]. When registering the + * listener to Vehicle.ADAS.ABS this listener will also be notified about changes of children e.g. + * Vehicle.ADAS.ABS.IsEnabled or Vehicle.ADAS.ABS.IsEngaged. */ interface PropertyListener : Listener { /** diff --git a/kuksa-sdk/src/main/kotlin/org/eclipse/kuksa/extension/DataPointExtension.kt b/kuksa-sdk/src/main/kotlin/org/eclipse/kuksa/extension/DataPointExtension.kt index 8c008667..3ecd3e8a 100644 --- a/kuksa-sdk/src/main/kotlin/org/eclipse/kuksa/extension/DataPointExtension.kt +++ b/kuksa-sdk/src/main/kotlin/org/eclipse/kuksa/extension/DataPointExtension.kt @@ -24,7 +24,7 @@ import org.eclipse.kuksa.proto.v1.Types import org.eclipse.kuksa.proto.v1.Types.BoolArray import org.eclipse.kuksa.proto.v1.Types.Datapoint import org.eclipse.kuksa.proto.v1.Types.Datapoint.ValueCase -import org.eclipse.kuksa.vsscore.model.VssProperty +import org.eclipse.kuksa.vsscore.model.VssLeaf private const val CSV_DELIMITER = "," @@ -35,11 +35,11 @@ val Types.Metadata.valueType: ValueCase get() = dataType.dataPointValueCase /** - * Converts the [VssProperty.value] into a [Datapoint] object. + * Converts the [VssLeaf.value] into a [Datapoint] object. * - * @throws IllegalArgumentException if the [VssProperty] could not be converted to a [Datapoint]. + * @throws IllegalArgumentException if the [VssLeaf] could not be converted to a [Datapoint]. */ -val VssProperty.datapoint: Datapoint +val VssLeaf.datapoint: Datapoint get() { val stringValue = value.toString() return when (value::class) { diff --git a/kuksa-sdk/src/main/kotlin/org/eclipse/kuksa/extension/VssSpecificationCopyExtension.kt b/kuksa-sdk/src/main/kotlin/org/eclipse/kuksa/extension/VssSpecificationCopyExtension.kt index 8a35c233..9d28e52f 100644 --- a/kuksa-sdk/src/main/kotlin/org/eclipse/kuksa/extension/VssSpecificationCopyExtension.kt +++ b/kuksa-sdk/src/main/kotlin/org/eclipse/kuksa/extension/VssSpecificationCopyExtension.kt @@ -22,7 +22,7 @@ package org.eclipse.kuksa.extension import org.eclipse.kuksa.proto.v1.Types import org.eclipse.kuksa.proto.v1.Types.Datapoint import org.eclipse.kuksa.proto.v1.Types.Datapoint.ValueCase.* -import org.eclipse.kuksa.vsscore.model.VssProperty +import org.eclipse.kuksa.vsscore.model.VssLeaf import org.eclipse.kuksa.vsscore.model.VssSpecification import org.eclipse.kuksa.vsscore.model.findHeritageLine import org.eclipse.kuksa.vsscore.model.heritage @@ -71,11 +71,11 @@ fun T.deepCopy(generation: Int = 0, vararg changedHeritag } /** - * Creates a copy of a [VssProperty] where the [VssProperty.value] is changed to the given [Datapoint]. + * Creates a copy of a [VssLeaf] where the [VssLeaf.value] is changed to the given [Datapoint]. */ // The actual value type is unknown but it is expected that the casted [valueCase] is valid if no exception was thrown. @Suppress("UNCHECKED_CAST") -fun VssProperty.copy(datapoint: Datapoint): VssProperty { +fun VssLeaf.copy(datapoint: Datapoint): VssLeaf { with(datapoint) { val value: Any = when (valueCase) { STRING -> string @@ -123,13 +123,13 @@ fun VssProperty.copy(datapoint: Datapoint): VssProperty { } /** - * Calls the generated copy method of the data class for the [VssProperty] and returns a new copy with the new [value]. + * Calls the generated copy method of the data class for the [VssLeaf] and returns a new copy with the new [value]. * * @throws [IllegalArgumentException] if the copied types do not match. * @throws [NoSuchElementException] if no copy method was found for the class. */ -fun VssProperty.copy(value: T): VssProperty { - val memberProperties = VssProperty::class.memberProperties +fun VssLeaf.copy(value: T): VssLeaf { + val memberProperties = VssLeaf::class.memberProperties val firstPropertyName = memberProperties.first().name val valueMap = mapOf(firstPropertyName to value) @@ -155,7 +155,7 @@ fun T.copy( ): T { val vssSpecifications = consideredHeritage + this val vssProperty = vssSpecifications - .filterIsInstance>() + .filterIsInstance>() .find { it.vssPath == vssPath } ?: return this val updatedVssProperty = vssProperty.copy(updatedValue) @@ -185,7 +185,7 @@ operator fun T.invoke(vararg property: VssSpecification): * @throws [IllegalArgumentException] if the copied types do not match. * @throws [NoSuchElementException] if no copy method was found for the class. */ -operator fun VssProperty.invoke(value: T): VssProperty { +operator fun VssLeaf.invoke(value: T): VssLeaf { return copy(value) } diff --git a/kuksa-sdk/src/main/kotlin/org/eclipse/kuksa/extension/VssSpecificationExtension.kt b/kuksa-sdk/src/main/kotlin/org/eclipse/kuksa/extension/VssSpecificationExtension.kt index e7c9a579..6e8496ea 100644 --- a/kuksa-sdk/src/main/kotlin/org/eclipse/kuksa/extension/VssSpecificationExtension.kt +++ b/kuksa-sdk/src/main/kotlin/org/eclipse/kuksa/extension/VssSpecificationExtension.kt @@ -20,12 +20,12 @@ package org.eclipse.kuksa.extension import org.eclipse.kuksa.model.Property import org.eclipse.kuksa.proto.v1.Types -import org.eclipse.kuksa.vsscore.model.VssProperty +import org.eclipse.kuksa.vsscore.model.VssLeaf import org.eclipse.kuksa.vsscore.model.VssSpecification import org.eclipse.kuksa.vsscore.model.vssProperties /** - * Finds all [VssProperty] heirs for the [VssSpecification] and converts them into a collection of [Property]. + * Finds all [VssLeaf] heirs for the [VssSpecification] and converts them into a collection of [Property]. */ fun VssSpecification.createProperties( vararg fields: Types.Field = arrayOf(Types.Field.FIELD_VALUE), diff --git a/kuksa-sdk/src/main/kotlin/org/eclipse/kuksa/extension/vssProperty/VssPropertyBooleanExtension.kt b/kuksa-sdk/src/main/kotlin/org/eclipse/kuksa/extension/vssProperty/VssPropertyBooleanExtension.kt index 8544834c..0bafa2f6 100644 --- a/kuksa-sdk/src/main/kotlin/org/eclipse/kuksa/extension/vssProperty/VssPropertyBooleanExtension.kt +++ b/kuksa-sdk/src/main/kotlin/org/eclipse/kuksa/extension/vssProperty/VssPropertyBooleanExtension.kt @@ -19,7 +19,7 @@ package org.eclipse.kuksa.extension.vssProperty import org.eclipse.kuksa.extension.copy -import org.eclipse.kuksa.vsscore.model.VssProperty +import org.eclipse.kuksa.vsscore.model.VssLeaf /** * Convenience operator for [copy] with a [Boolean] value which will be inverted. @@ -27,6 +27,6 @@ import org.eclipse.kuksa.vsscore.model.VssProperty * @throws [IllegalArgumentException] if the copied types do not match. * @throws [NoSuchElementException] if no copy method was found for the class. */ -operator fun VssProperty.not(): VssProperty { +operator fun VssLeaf.not(): VssLeaf { return copy(!value) } diff --git a/kuksa-sdk/src/main/kotlin/org/eclipse/kuksa/extension/vssProperty/VssPropertyDoubleExtension.kt b/kuksa-sdk/src/main/kotlin/org/eclipse/kuksa/extension/vssProperty/VssPropertyDoubleExtension.kt index 37ef935b..072255af 100644 --- a/kuksa-sdk/src/main/kotlin/org/eclipse/kuksa/extension/vssProperty/VssPropertyDoubleExtension.kt +++ b/kuksa-sdk/src/main/kotlin/org/eclipse/kuksa/extension/vssProperty/VssPropertyDoubleExtension.kt @@ -19,86 +19,86 @@ package org.eclipse.kuksa.extension.vssProperty import org.eclipse.kuksa.extension.copy -import org.eclipse.kuksa.vsscore.model.VssProperty +import org.eclipse.kuksa.vsscore.model.VssLeaf /** - * Convenience operator for [copy] which updates the [VssProperty.value] by adding [value] to it. + * Convenience operator for [copy] which updates the [VssLeaf.value] by adding [value] to it. * * @throws [IllegalArgumentException] if the copied types do not match. * @throws [NoSuchElementException] if no copy method was found for the class. */ -operator fun VssProperty.plusAssign(value: Number) { +operator fun VssLeaf.plusAssign(value: Number) { copy(this.value + value.toDouble()) } /** - * Convenience operator for [copy] which updates the [VssProperty.value] by adding [value] to it. + * Convenience operator for [copy] which updates the [VssLeaf.value] by adding [value] to it. * * @throws [IllegalArgumentException] if the copied types do not match. * @throws [NoSuchElementException] if no copy method was found for the class. */ -operator fun VssProperty.plus(value: Number): VssProperty { +operator fun VssLeaf.plus(value: Number): VssLeaf { return copy(this.value + value.toDouble()) } /** - * Convenience operator for [copy] which updates the [VssProperty.value] by subtracting [value] to it. + * Convenience operator for [copy] which updates the [VssLeaf.value] by subtracting [value] to it. * * @throws [IllegalArgumentException] if the copied types do not match. * @throws [NoSuchElementException] if no copy method was found for the class. */ -operator fun VssProperty.minusAssign(value: Number) { +operator fun VssLeaf.minusAssign(value: Number) { copy(this.value - value.toDouble()) } /** - * Convenience operator for [copy] which updates the [VssProperty.value] by subtracting [value] to it. + * Convenience operator for [copy] which updates the [VssLeaf.value] by subtracting [value] to it. * * @throws [IllegalArgumentException] if the copied types do not match. * @throws [NoSuchElementException] if no copy method was found for the class. */ -operator fun VssProperty.minus(value: Number): VssProperty { +operator fun VssLeaf.minus(value: Number): VssLeaf { return copy(this.value - value.toDouble()) } /** - * Convenience operator for [copy] which updates the [VssProperty.value] by dividing [value] to it. + * Convenience operator for [copy] which updates the [VssLeaf.value] by dividing [value] to it. * * @throws [IllegalArgumentException] if the copied types do not match. * @throws [NoSuchElementException] if no copy method was found for the class. * @throws [ArithmeticException] if divided by zero. */ -operator fun VssProperty.divAssign(value: Number) { +operator fun VssLeaf.divAssign(value: Number) { copy(this.value / value.toDouble()) } /** - * Convenience operator for [copy] which updates the [VssProperty.value] by dividing [value] to it. + * Convenience operator for [copy] which updates the [VssLeaf.value] by dividing [value] to it. * * @throws [IllegalArgumentException] if the copied types do not match. * @throws [NoSuchElementException] if no copy method was found for the class. * @throws [ArithmeticException] if divided by zero. */ -operator fun VssProperty.div(value: Number): VssProperty { +operator fun VssLeaf.div(value: Number): VssLeaf { return copy(this.value / value.toDouble()) } /** - * Convenience operator for [copy] which updates the [VssProperty.value] by multiplying [value] to it. + * Convenience operator for [copy] which updates the [VssLeaf.value] by multiplying [value] to it. * * @throws [IllegalArgumentException] if the copied types do not match. * @throws [NoSuchElementException] if no copy method was found for the class. */ -operator fun VssProperty.timesAssign(value: Number) { +operator fun VssLeaf.timesAssign(value: Number) { copy(this.value * value.toDouble()) } /** - * Convenience operator for [copy] which updates the [VssProperty.value] by multiplying [value] to it. + * Convenience operator for [copy] which updates the [VssLeaf.value] by multiplying [value] to it. * * @throws [IllegalArgumentException] if the copied types do not match. * @throws [NoSuchElementException] if no copy method was found for the class. */ -operator fun VssProperty.times(value: Number): VssProperty { +operator fun VssLeaf.times(value: Number): VssLeaf { return copy(this.value * value.toDouble()) } diff --git a/kuksa-sdk/src/main/kotlin/org/eclipse/kuksa/extension/vssProperty/VssPropertyFloatExtension.kt b/kuksa-sdk/src/main/kotlin/org/eclipse/kuksa/extension/vssProperty/VssPropertyFloatExtension.kt index 91d090f0..cefadaa7 100644 --- a/kuksa-sdk/src/main/kotlin/org/eclipse/kuksa/extension/vssProperty/VssPropertyFloatExtension.kt +++ b/kuksa-sdk/src/main/kotlin/org/eclipse/kuksa/extension/vssProperty/VssPropertyFloatExtension.kt @@ -19,86 +19,86 @@ package org.eclipse.kuksa.extension.vssProperty import org.eclipse.kuksa.extension.copy -import org.eclipse.kuksa.vsscore.model.VssProperty +import org.eclipse.kuksa.vsscore.model.VssLeaf /** - * Convenience operator for [copy] which updates the [VssProperty.value] by adding [value] to it. + * Convenience operator for [copy] which updates the [VssLeaf.value] by adding [value] to it. * * @throws [IllegalArgumentException] if the copied types do not match. * @throws [NoSuchElementException] if no copy method was found for the class. */ -operator fun VssProperty.plusAssign(value: Number) { +operator fun VssLeaf.plusAssign(value: Number) { copy(this.value + value.toFloat()) } /** - * Convenience operator for [copy] which updates the [VssProperty.value] by adding [value] to it. + * Convenience operator for [copy] which updates the [VssLeaf.value] by adding [value] to it. * * @throws [IllegalArgumentException] if the copied types do not match. * @throws [NoSuchElementException] if no copy method was found for the class. */ -operator fun VssProperty.plus(value: Number): VssProperty { +operator fun VssLeaf.plus(value: Number): VssLeaf { return copy(this.value + value.toFloat()) } /** - * Convenience operator for [copy] which updates the [VssProperty.value] by subtracting [value] to it. + * Convenience operator for [copy] which updates the [VssLeaf.value] by subtracting [value] to it. * * @throws [IllegalArgumentException] if the copied types do not match. * @throws [NoSuchElementException] if no copy method was found for the class. */ -operator fun VssProperty.minusAssign(value: Number) { +operator fun VssLeaf.minusAssign(value: Number) { copy(this.value - +value.toFloat()) } /** - * Convenience operator for [copy] which updates the [VssProperty.value] by subtracting [value] to it. + * Convenience operator for [copy] which updates the [VssLeaf.value] by subtracting [value] to it. * * @throws [IllegalArgumentException] if the copied types do not match. * @throws [NoSuchElementException] if no copy method was found for the class. */ -operator fun VssProperty.minus(value: Number): VssProperty { +operator fun VssLeaf.minus(value: Number): VssLeaf { return copy(this.value - +value.toFloat()) } /** - * Convenience operator for [copy] which updates the [VssProperty.value] by dividing [value] to it. + * Convenience operator for [copy] which updates the [VssLeaf.value] by dividing [value] to it. * * @throws [IllegalArgumentException] if the copied types do not match. * @throws [NoSuchElementException] if no copy method was found for the class. * @throws [ArithmeticException] if divided by zero. */ -operator fun VssProperty.divAssign(value: Number) { +operator fun VssLeaf.divAssign(value: Number) { copy(this.value / +value.toFloat()) } /** - * Convenience operator for [copy] which updates the [VssProperty.value] by dividing [value] to it. + * Convenience operator for [copy] which updates the [VssLeaf.value] by dividing [value] to it. * * @throws [IllegalArgumentException] if the copied types do not match. * @throws [NoSuchElementException] if no copy method was found for the class. * @throws [ArithmeticException] if divided by zero. */ -operator fun VssProperty.div(value: Number): VssProperty { +operator fun VssLeaf.div(value: Number): VssLeaf { return copy(this.value / +value.toFloat()) } /** - * Convenience operator for [copy] which updates the [VssProperty.value] by dividing [value] to it. + * Convenience operator for [copy] which updates the [VssLeaf.value] by dividing [value] to it. * * @throws [IllegalArgumentException] if the copied types do not match. * @throws [NoSuchElementException] if no copy method was found for the class. */ -operator fun VssProperty.timesAssign(value: Number) { +operator fun VssLeaf.timesAssign(value: Number) { copy(this.value * +value.toFloat()) } /** - * Convenience operator for [copy] which updates the [VssProperty.value] by dividing [value] to it. + * Convenience operator for [copy] which updates the [VssLeaf.value] by dividing [value] to it. * * @throws [IllegalArgumentException] if the copied types do not match. * @throws [NoSuchElementException] if no copy method was found for the class. */ -operator fun VssProperty.times(value: Number): VssProperty { +operator fun VssLeaf.times(value: Number): VssLeaf { return copy(this.value * +value.toFloat()) } diff --git a/kuksa-sdk/src/main/kotlin/org/eclipse/kuksa/extension/vssProperty/VssPropertyIntExtension.kt b/kuksa-sdk/src/main/kotlin/org/eclipse/kuksa/extension/vssProperty/VssPropertyIntExtension.kt index 3a8baf41..d2b905bb 100644 --- a/kuksa-sdk/src/main/kotlin/org/eclipse/kuksa/extension/vssProperty/VssPropertyIntExtension.kt +++ b/kuksa-sdk/src/main/kotlin/org/eclipse/kuksa/extension/vssProperty/VssPropertyIntExtension.kt @@ -19,86 +19,86 @@ package org.eclipse.kuksa.extension.vssProperty import org.eclipse.kuksa.extension.copy -import org.eclipse.kuksa.vsscore.model.VssProperty +import org.eclipse.kuksa.vsscore.model.VssLeaf /** - * Convenience operator for [copy] which updates the [VssProperty.value] by adding [value] to it. + * Convenience operator for [copy] which updates the [VssLeaf.value] by adding [value] to it. * * @throws [IllegalArgumentException] if the copied types do not match. * @throws [NoSuchElementException] if no copy method was found for the class. */ -operator fun VssProperty.plusAssign(value: Number) { +operator fun VssLeaf.plusAssign(value: Number) { copy(this.value + value.toInt()) } /** - * Convenience operator for [copy] which updates the [VssProperty.value] by adding [value] to it. + * Convenience operator for [copy] which updates the [VssLeaf.value] by adding [value] to it. * * @throws [IllegalArgumentException] if the copied types do not match. * @throws [NoSuchElementException] if no copy method was found for the class. */ -operator fun VssProperty.plus(value: Number): VssProperty { +operator fun VssLeaf.plus(value: Number): VssLeaf { return copy(this.value + value.toInt()) } /** - * Convenience operator for [copy] which updates the [VssProperty.value] by subtracting [value] to it. + * Convenience operator for [copy] which updates the [VssLeaf.value] by subtracting [value] to it. * * @throws [IllegalArgumentException] if the copied types do not match. * @throws [NoSuchElementException] if no copy method was found for the class. */ -operator fun VssProperty.minusAssign(value: Number) { +operator fun VssLeaf.minusAssign(value: Number) { copy(this.value - value.toInt()) } /** - * Convenience operator for [copy] which updates the [VssProperty.value] by subtracting [value] to it. + * Convenience operator for [copy] which updates the [VssLeaf.value] by subtracting [value] to it. * * @throws [IllegalArgumentException] if the copied types do not match. * @throws [NoSuchElementException] if no copy method was found for the class. */ -operator fun VssProperty.minus(value: Number): VssProperty { +operator fun VssLeaf.minus(value: Number): VssLeaf { return copy(this.value - value.toInt()) } /** - * Convenience operator for [copy] which updates the [VssProperty.value] by dividing [value] to it. + * Convenience operator for [copy] which updates the [VssLeaf.value] by dividing [value] to it. * * @throws [IllegalArgumentException] if the copied types do not match. * @throws [NoSuchElementException] if no copy method was found for the class. * @throws [ArithmeticException] if divided by zero. */ -operator fun VssProperty.divAssign(value: Number) { +operator fun VssLeaf.divAssign(value: Number) { copy(this.value / value.toInt()) } /** - * Convenience operator for [copy] which updates the [VssProperty.value] by dividing [value] to it. + * Convenience operator for [copy] which updates the [VssLeaf.value] by dividing [value] to it. * * @throws [IllegalArgumentException] if the copied types do not match. * @throws [NoSuchElementException] if no copy method was found for the class. * @throws [ArithmeticException] if divided by zero. */ -operator fun VssProperty.div(value: Number): VssProperty { +operator fun VssLeaf.div(value: Number): VssLeaf { return copy(this.value / value.toInt()) } /** - * Convenience operator for [copy] which updates the [VssProperty.value] by multiplying [value] to it. + * Convenience operator for [copy] which updates the [VssLeaf.value] by multiplying [value] to it. * * @throws [IllegalArgumentException] if the copied types do not match. * @throws [NoSuchElementException] if no copy method was found for the class. */ -operator fun VssProperty.timesAssign(value: Number) { +operator fun VssLeaf.timesAssign(value: Number) { copy(this.value * value.toInt()) } /** - * Convenience operator for [copy] which updates the [VssProperty.value] by multiplying [value] to it. + * Convenience operator for [copy] which updates the [VssLeaf.value] by multiplying [value] to it. * * @throws [IllegalArgumentException] if the copied types do not match. * @throws [NoSuchElementException] if no copy method was found for the class. */ -operator fun VssProperty.times(value: Number): VssProperty { +operator fun VssLeaf.times(value: Number): VssLeaf { return copy(this.value * value.toInt()) } diff --git a/kuksa-sdk/src/main/kotlin/org/eclipse/kuksa/extension/vssProperty/VssPropertyLongExtension.kt b/kuksa-sdk/src/main/kotlin/org/eclipse/kuksa/extension/vssProperty/VssPropertyLongExtension.kt index 716d3b19..d8bf749c 100644 --- a/kuksa-sdk/src/main/kotlin/org/eclipse/kuksa/extension/vssProperty/VssPropertyLongExtension.kt +++ b/kuksa-sdk/src/main/kotlin/org/eclipse/kuksa/extension/vssProperty/VssPropertyLongExtension.kt @@ -19,86 +19,86 @@ package org.eclipse.kuksa.extension.vssProperty import org.eclipse.kuksa.extension.copy -import org.eclipse.kuksa.vsscore.model.VssProperty +import org.eclipse.kuksa.vsscore.model.VssLeaf /** - * Convenience operator for [copy] which updates the [VssProperty.value] by adding [value] to it. + * Convenience operator for [copy] which updates the [VssLeaf.value] by adding [value] to it. * * @throws [IllegalArgumentException] if the copied types do not match. * @throws [NoSuchElementException] if no copy method was found for the class. */ -operator fun VssProperty.plusAssign(value: Number) { +operator fun VssLeaf.plusAssign(value: Number) { copy(this.value + value.toLong()) } /** - * Convenience operator for [copy] which updates the [VssProperty.value] by adding [value] to it. + * Convenience operator for [copy] which updates the [VssLeaf.value] by adding [value] to it. * * @throws [IllegalArgumentException] if the copied types do not match. * @throws [NoSuchElementException] if no copy method was found for the class. */ -operator fun VssProperty.plus(value: Number): VssProperty { +operator fun VssLeaf.plus(value: Number): VssLeaf { return copy(this.value + value.toLong()) } /** - * Convenience operator for [copy] which updates the [VssProperty.value] by subtracting [value] to it. + * Convenience operator for [copy] which updates the [VssLeaf.value] by subtracting [value] to it. * * @throws [IllegalArgumentException] if the copied types do not match. * @throws [NoSuchElementException] if no copy method was found for the class. */ -operator fun VssProperty.minusAssign(value: Number) { +operator fun VssLeaf.minusAssign(value: Number) { copy(this.value - value.toLong()) } /** - * Convenience operator for [copy] which updates the [VssProperty.value] by subtracting [value] to it. + * Convenience operator for [copy] which updates the [VssLeaf.value] by subtracting [value] to it. * * @throws [IllegalArgumentException] if the copied types do not match. * @throws [NoSuchElementException] if no copy method was found for the class. */ -operator fun VssProperty.minus(value: Number): VssProperty { +operator fun VssLeaf.minus(value: Number): VssLeaf { return copy(this.value - value.toLong()) } /** - * Convenience operator for [copy] which updates the [VssProperty.value] by dividing [value] to it. + * Convenience operator for [copy] which updates the [VssLeaf.value] by dividing [value] to it. * * @throws [IllegalArgumentException] if the copied types do not match. * @throws [NoSuchElementException] if no copy method was found for the class. * @throws [ArithmeticException] if divided by zero. */ -operator fun VssProperty.divAssign(value: Number) { +operator fun VssLeaf.divAssign(value: Number) { copy(this.value / value.toLong()) } /** - * Convenience operator for [copy] which updates the [VssProperty.value] by dividing [value] to it. + * Convenience operator for [copy] which updates the [VssLeaf.value] by dividing [value] to it. * * @throws [IllegalArgumentException] if the copied types do not match. * @throws [NoSuchElementException] if no copy method was found for the class. * @throws [ArithmeticException] if divided by zero. */ -operator fun VssProperty.div(value: Number): VssProperty { +operator fun VssLeaf.div(value: Number): VssLeaf { return copy(this.value / value.toLong()) } /** - * Convenience operator for [copy] which updates the [VssProperty.value] by multiplying [value] to it. + * Convenience operator for [copy] which updates the [VssLeaf.value] by multiplying [value] to it. * * @throws [IllegalArgumentException] if the copied types do not match. * @throws [NoSuchElementException] if no copy method was found for the class. */ -operator fun VssProperty.timesAssign(value: Number) { +operator fun VssLeaf.timesAssign(value: Number) { copy(this.value * value.toLong()) } /** - * Convenience operator for [copy] which updates the [VssProperty.value] by multiplying [value] to it. + * Convenience operator for [copy] which updates the [VssLeaf.value] by multiplying [value] to it. * * @throws [IllegalArgumentException] if the copied types do not match. * @throws [NoSuchElementException] if no copy method was found for the class. */ -operator fun VssProperty.times(value: Number): VssProperty { +operator fun VssLeaf.times(value: Number): VssLeaf { return copy(this.value * value.toLong()) } diff --git a/kuksa-sdk/src/main/kotlin/org/eclipse/kuksa/model/Property.kt b/kuksa-sdk/src/main/kotlin/org/eclipse/kuksa/model/Property.kt index b5bffda8..57aece91 100644 --- a/kuksa-sdk/src/main/kotlin/org/eclipse/kuksa/model/Property.kt +++ b/kuksa-sdk/src/main/kotlin/org/eclipse/kuksa/model/Property.kt @@ -32,7 +32,7 @@ data class Property( val vssPath: String, /** - * The corresponding field type of the Property. The default is [FIELD_VALUE]. + * The corresponding field type of the [Property]. The default is [FIELD_VALUE]. */ val fields: Collection = listOf(FIELD_VALUE), ) diff --git a/kuksa-sdk/src/main/kotlin/org/eclipse/kuksa/subscription/DataBrokerSubscriber.kt b/kuksa-sdk/src/main/kotlin/org/eclipse/kuksa/subscription/DataBrokerSubscriber.kt index f95678fe..306942a7 100644 --- a/kuksa-sdk/src/main/kotlin/org/eclipse/kuksa/subscription/DataBrokerSubscriber.kt +++ b/kuksa-sdk/src/main/kotlin/org/eclipse/kuksa/subscription/DataBrokerSubscriber.kt @@ -27,7 +27,7 @@ import org.eclipse.kuksa.VssSpecificationListener import org.eclipse.kuksa.extension.TAG import org.eclipse.kuksa.proto.v1.Types import org.eclipse.kuksa.proto.v1.Types.Field -import org.eclipse.kuksa.vsscore.model.VssProperty +import org.eclipse.kuksa.vsscore.model.VssLeaf import org.eclipse.kuksa.vsscore.model.VssSpecification /** @@ -76,10 +76,10 @@ internal class DataBrokerSubscriber(private val dataBrokerTransporter: DataBroke } /** - * Subscribes to the specified [VssSpecification] with the provided [VssSpecificationListener]. Only a [VssProperty] + * Subscribes to the specified [VssSpecification] with the provided [VssSpecificationListener]. Only a [VssLeaf] * can be subscribed because they have an actual value. When provided with any parent [VssSpecification] then this - * [subscribe] method will find all [VssProperty] children and subscribes them instead. Once subscribed the - * application will be notified about any changes to every subscribed [VssProperty]. The [field] can be used to + * [subscribe] method will find all [VssLeaf] children and subscribes them instead. Once subscribed the + * application will be notified about any changes to every subscribed [VssLeaf]. The [field] can be used to * subscribe to different information of the [specification]. The default for the [field] parameter is a single * [Types.Field.FIELD_VALUE] entry. * diff --git a/kuksa-sdk/src/test/kotlin/org/eclipse/kuksa/vssSpecification/VssDriver.kt b/kuksa-sdk/src/test/kotlin/org/eclipse/kuksa/vssSpecification/VssDriver.kt index 6d3f6999..9b9e447e 100644 --- a/kuksa-sdk/src/test/kotlin/org/eclipse/kuksa/vssSpecification/VssDriver.kt +++ b/kuksa-sdk/src/test/kotlin/org/eclipse/kuksa/vssSpecification/VssDriver.kt @@ -19,7 +19,7 @@ package org.eclipse.kuksa.vssSpecification -import org.eclipse.kuksa.vsscore.model.VssProperty +import org.eclipse.kuksa.vsscore.model.VssLeaf import org.eclipse.kuksa.vsscore.model.VssSpecification import kotlin.reflect.KClass @@ -63,7 +63,7 @@ data class VssDriver @JvmOverloads constructor( data class VssHeartRate @JvmOverloads constructor( override val `value`: Int = 0, - ) : VssProperty { + ) : VssLeaf { override val comment: String get() = "" @@ -89,7 +89,7 @@ data class VssDriver @JvmOverloads constructor( data class VssAttentiveProbability @JvmOverloads constructor( override val `value`: Float = 0f, -) : VssProperty { +) : VssLeaf { override val comment: String get() = "" @@ -114,7 +114,7 @@ data class VssAttentiveProbability @JvmOverloads constructor( data class VssDistractionLevel @JvmOverloads constructor( override val `value`: Float = 0f, -) : VssProperty { +) : VssLeaf { override val comment: String get() = "" @@ -139,7 +139,7 @@ data class VssDistractionLevel @JvmOverloads constructor( data class VssFatigueLevel @JvmOverloads constructor( override val `value`: Float = 0f, -) : VssProperty { +) : VssLeaf { override val comment: String get() = "" @@ -190,7 +190,7 @@ data class VssIdentifier @JvmOverloads constructor( data class VssIssuer @JvmOverloads constructor( override val `value`: String = "", -) : VssProperty { +) : VssLeaf { override val comment: String get() = "" @@ -216,7 +216,7 @@ data class VssIssuer @JvmOverloads constructor( data class VssSubject @JvmOverloads constructor( override val `value`: String = "", -) : VssProperty { +) : VssLeaf { override val comment: String get() = "" @@ -241,7 +241,7 @@ data class VssSubject @JvmOverloads constructor( data class VssIsEyesOnRoad @JvmOverloads constructor( override val `value`: Boolean = false, -) : VssProperty { +) : VssLeaf { override val comment: String get() = "" @@ -266,7 +266,7 @@ data class VssIsEyesOnRoad @JvmOverloads constructor( data class VssIsHandsOnWheel @JvmOverloads constructor( override val `value`: Boolean = false, -) : VssProperty { +) : VssLeaf { override val comment: String get() = "" diff --git a/kuksa-sdk/src/test/kotlin/org/eclipse/kuksa/vssSpecification/VssSpecificationCopyTest.kt b/kuksa-sdk/src/test/kotlin/org/eclipse/kuksa/vssSpecification/VssSpecificationCopyTest.kt index 8499acd2..a9102ce2 100644 --- a/kuksa-sdk/src/test/kotlin/org/eclipse/kuksa/vssSpecification/VssSpecificationCopyTest.kt +++ b/kuksa-sdk/src/test/kotlin/org/eclipse/kuksa/vssSpecification/VssSpecificationCopyTest.kt @@ -30,14 +30,14 @@ import org.eclipse.kuksa.extension.invoke import org.eclipse.kuksa.extension.vssProperty.not import org.eclipse.kuksa.proto.v1.Types import org.eclipse.kuksa.test.kotest.Unit -import org.eclipse.kuksa.vsscore.model.VssProperty +import org.eclipse.kuksa.vsscore.model.VssLeaf class VssSpecificationCopyTest : BehaviorSpec({ tags(Unit) given("A specification") { val vehicle = VssVehicle() - val driverHeartRate: VssProperty = vehicle.driver.heartRate + val driverHeartRate: VssLeaf = vehicle.driver.heartRate and("a changed heritage line") { val newValue = 70 diff --git a/kuksa-sdk/src/test/kotlin/org/eclipse/kuksa/vssSpecification/VssVehicle.kt b/kuksa-sdk/src/test/kotlin/org/eclipse/kuksa/vssSpecification/VssVehicle.kt index 6abebf3d..a3431570 100644 --- a/kuksa-sdk/src/test/kotlin/org/eclipse/kuksa/vssSpecification/VssVehicle.kt +++ b/kuksa-sdk/src/test/kotlin/org/eclipse/kuksa/vssSpecification/VssVehicle.kt @@ -19,7 +19,7 @@ package org.eclipse.kuksa.vssSpecification -import org.eclipse.kuksa.vsscore.model.VssProperty +import org.eclipse.kuksa.vsscore.model.VssLeaf import org.eclipse.kuksa.vsscore.model.VssSpecification import kotlin.reflect.KClass @@ -68,7 +68,7 @@ data class VssPassenger( override val type: String = "sensor", override val comment: String = "", override val value: Int = 80, - ) : VssProperty { + ) : VssLeaf { override val parentClass: KClass<*> get() = VssPassenger::class } @@ -81,7 +81,7 @@ data class VssValueInt( override val type: String = "sensor", override val comment: String = "", override val value: Int = 0, -) : VssProperty +) : VssLeaf data class VssValueFloat( override val uuid: String = "Value", @@ -90,7 +90,7 @@ data class VssValueFloat( override val type: String = "sensor", override val comment: String = "", override val value: Float = 0f, -) : VssProperty +) : VssLeaf data class VssValueDouble( override val uuid: String = "Value", @@ -99,7 +99,7 @@ data class VssValueDouble( override val type: String = "sensor", override val comment: String = "", override val value: Double = 0.0, -) : VssProperty +) : VssLeaf data class VssValueLong( override val uuid: String = "Value", @@ -108,7 +108,7 @@ data class VssValueLong( override val type: String = "sensor", override val comment: String = "", override val value: Long = 0L, -) : VssProperty +) : VssLeaf data class VssInvalid( override val uuid: String = "Invalid", @@ -117,4 +117,4 @@ data class VssInvalid( override val type: String = "", override val comment: String = "", override val value: Exception = Exception(), -) : VssProperty +) : VssLeaf diff --git a/vss-core/src/main/java/org/eclipse/kuksa/vsscore/model/VssSpecification.kt b/vss-core/src/main/java/org/eclipse/kuksa/vsscore/model/VssSpecification.kt index 48747baa..6e402f7b 100644 --- a/vss-core/src/main/java/org/eclipse/kuksa/vsscore/model/VssSpecification.kt +++ b/vss-core/src/main/java/org/eclipse/kuksa/vsscore/model/VssSpecification.kt @@ -55,7 +55,7 @@ interface VssSpecification : VssNode { /** * Some [VssSpecification] may have an additional [value] property. These are children which are not parents. */ -interface VssProperty : VssSpecification { +interface VssLeaf : VssSpecification { val value: T } @@ -118,12 +118,12 @@ val VssSpecification.heritage: Collection get() = children.toList() + children.flatMap { it.heritage } /** - * Finds the latest generation in the form of [VssProperty] for the current [VssSpecification]. + * Finds the latest generation in the form of [VssLeaf] for the current [VssSpecification]. */ -val VssSpecification.vssProperties: Collection> +val VssSpecification.vssProperties: Collection> get() = heritage .ifEmpty { setOf(this) } - .filterIsInstance>() + .filterIsInstance>() /** * Uses the [variablePrefix] to generate a unique variable name. The first character is at least lowercased. @@ -192,19 +192,19 @@ fun VssSpecification.findHeritageLine( /** * Finds the given [property] inside the current [VssSpecification]. */ -fun , V : Any> VssSpecification.findProperty(property: VssProperty): VssProperty { +fun , V : Any> VssSpecification.findProperty(property: VssLeaf): VssLeaf { return heritage - .filterIsInstance>() + .filterIsInstance>() .first { it.uuid == property.uuid } } /** - * Finds all [VssProperty] which matches the given [KClass.simpleName]. This is useful when multiple nested objects + * Finds all [VssLeaf] which matches the given [KClass.simpleName]. This is useful when multiple nested objects * with the same Name exists but are pretty much the same besides the [VssSpecification.vssPath] etc. */ -fun , V : Any> VssSpecification.findProperties(type: KClass): Map> { +fun , V : Any> VssSpecification.findProperties(type: KClass): Map> { return heritage - .filterIsInstance>() + .filterIsInstance>() .filter { it::class.simpleName == type.simpleName } .associateBy { it.vssPath } } diff --git a/vss-core/src/test/java/org/eclipse/kuksa/vsscore/model/VssVehicle.kt b/vss-core/src/test/java/org/eclipse/kuksa/vsscore/model/VssVehicle.kt index 68e0bac9..2cc80336 100644 --- a/vss-core/src/test/java/org/eclipse/kuksa/vsscore/model/VssVehicle.kt +++ b/vss-core/src/test/java/org/eclipse/kuksa/vsscore/model/VssVehicle.kt @@ -66,7 +66,7 @@ data class VssDriver( override val type: String = "sensor", override val comment: String = "", override val value: Int = 100, - ) : VssProperty { + ) : VssLeaf { override val parentClass: KClass<*> get() = VssDriver::class } @@ -92,7 +92,7 @@ data class VssPassenger( override val type: String = "sensor", override val comment: String = "", override val value: Int = 80, - ) : VssProperty { + ) : VssLeaf { override val parentClass: KClass<*> get() = VssPassenger::class } diff --git a/vss-processor/src/main/kotlin/org/eclipse/kuksa/vssprocessor/spec/VssSpecificationSpecModel.kt b/vss-processor/src/main/kotlin/org/eclipse/kuksa/vssprocessor/spec/VssSpecificationSpecModel.kt index eba569b2..5a0efe34 100644 --- a/vss-processor/src/main/kotlin/org/eclipse/kuksa/vssprocessor/spec/VssSpecificationSpecModel.kt +++ b/vss-processor/src/main/kotlin/org/eclipse/kuksa/vssprocessor/spec/VssSpecificationSpecModel.kt @@ -33,7 +33,7 @@ import com.squareup.kotlinpoet.TypeSpec import com.squareup.kotlinpoet.asClassName import com.squareup.kotlinpoet.asTypeName import org.eclipse.kuksa.vsscore.model.VssNode -import org.eclipse.kuksa.vsscore.model.VssProperty +import org.eclipse.kuksa.vsscore.model.VssLeaf import org.eclipse.kuksa.vsscore.model.VssSpecification import org.eclipse.kuksa.vsscore.model.className import org.eclipse.kuksa.vsscore.model.name @@ -121,7 +121,7 @@ internal class VssSpecificationSpecModel( // Final leafs should ONLY implement the vss property interface superInterfaces.clear() - val vssPropertyInterface = VssProperty::class + val vssPropertyInterface = VssLeaf::class .asTypeName() .plusParameter(datatypeProperty) superInterfaces.add(vssPropertyInterface) @@ -292,13 +292,12 @@ internal class VssSpecificationSpecModel( val propertySpecs = mutableListOf() val members = VssNode::class.declaredMemberProperties + val setTypeName = Set::class.parameterizedBy(VssSpecification::class) + val classTypeName = KClass::class.asClassName().parameterizedBy(STAR).copy(nullable = true) members.forEach { member -> val memberName = member.name - val memberType = member.returnType.asTypeName() - val setTypeName = Set::class.parameterizedBy(VssSpecification::class) - val classTypeName = KClass::class.asClassName().parameterizedBy(STAR).copy(nullable = true) - val propertySpec: PropertySpec? = when (memberType) { + val propertySpec: PropertySpec? = when (val memberType = member.returnType.asTypeName()) { setTypeName -> createSetSpec(memberName, memberType) classTypeName -> createParentSpec(memberName, memberType) else -> null From 5dbcb42ce4007c75bb39e0f5dc15119246d5484e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mark=20Hu=CC=88sers?= Date: Wed, 28 Feb 2024 16:46:23 +0100 Subject: [PATCH 02/20] chore: Combine VssNode + VssSpecification The VssNode interface is already a good name for the defined VssSpecification properties. --- .../kuksa/vsscore/model/VssSpecification.kt | 23 ++++++++----------- .../vssprocessor/VssDefinitionProcessor.kt | 1 - .../spec/VssSpecificationSpecModel.kt | 13 +++++------ 3 files changed, 15 insertions(+), 22 deletions(-) diff --git a/vss-core/src/main/java/org/eclipse/kuksa/vsscore/model/VssSpecification.kt b/vss-core/src/main/java/org/eclipse/kuksa/vsscore/model/VssSpecification.kt index 6e402f7b..7acd8f38 100644 --- a/vss-core/src/main/java/org/eclipse/kuksa/vsscore/model/VssSpecification.kt +++ b/vss-core/src/main/java/org/eclipse/kuksa/vsscore/model/VssSpecification.kt @@ -24,9 +24,16 @@ import kotlin.reflect.KClass import kotlin.reflect.full.declaredMemberProperties /** - * Represents a node inside a VSS specification file. + * Represents a node inside a VSS specification file. it represents the most common properties of a VSS specification. + * The [uuid] is a mandatory field and should never be empty. */ -interface VssNode { +interface VssSpecification { + val uuid: String + val vssPath: String + val description: String + val type: String + val comment: String + /** * A collection of all initialized children. */ @@ -40,18 +47,6 @@ interface VssNode { get() = null } -/** - * In addition of being a [VssNode] it represents the most common properties of a VSS specification. The [uuid] is a - * mandatory field and should never be empty. - */ -interface VssSpecification : VssNode { - val uuid: String - val vssPath: String - val description: String - val type: String - val comment: String -} - /** * Some [VssSpecification] may have an additional [value] property. These are children which are not parents. */ diff --git a/vss-processor/src/main/kotlin/org/eclipse/kuksa/vssprocessor/VssDefinitionProcessor.kt b/vss-processor/src/main/kotlin/org/eclipse/kuksa/vssprocessor/VssDefinitionProcessor.kt index dee2f658..1d190b75 100644 --- a/vss-processor/src/main/kotlin/org/eclipse/kuksa/vssprocessor/VssDefinitionProcessor.kt +++ b/vss-processor/src/main/kotlin/org/eclipse/kuksa/vssprocessor/VssDefinitionProcessor.kt @@ -37,7 +37,6 @@ import com.squareup.kotlinpoet.FileSpec import com.squareup.kotlinpoet.ksp.toClassName import com.squareup.kotlinpoet.ksp.writeTo import org.eclipse.kuksa.vsscore.annotation.VssDefinition -import org.eclipse.kuksa.vsscore.model.VssNode import org.eclipse.kuksa.vsscore.model.parentClassName import org.eclipse.kuksa.vssprocessor.parser.YamlDefinitionParser import org.eclipse.kuksa.vssprocessor.spec.VssPath diff --git a/vss-processor/src/main/kotlin/org/eclipse/kuksa/vssprocessor/spec/VssSpecificationSpecModel.kt b/vss-processor/src/main/kotlin/org/eclipse/kuksa/vssprocessor/spec/VssSpecificationSpecModel.kt index 5a0efe34..2eb86cac 100644 --- a/vss-processor/src/main/kotlin/org/eclipse/kuksa/vssprocessor/spec/VssSpecificationSpecModel.kt +++ b/vss-processor/src/main/kotlin/org/eclipse/kuksa/vssprocessor/spec/VssSpecificationSpecModel.kt @@ -32,7 +32,6 @@ import com.squareup.kotlinpoet.TypeName import com.squareup.kotlinpoet.TypeSpec import com.squareup.kotlinpoet.asClassName import com.squareup.kotlinpoet.asTypeName -import org.eclipse.kuksa.vsscore.model.VssNode import org.eclipse.kuksa.vsscore.model.VssLeaf import org.eclipse.kuksa.vsscore.model.VssSpecification import org.eclipse.kuksa.vsscore.model.className @@ -127,7 +126,7 @@ internal class VssSpecificationSpecModel( superInterfaces.add(vssPropertyInterface) } - val propertySpec = createVssSpecificationSpecs(className, packageName = packageName) + val propertySpec = createVssNodeSpecs(className, packageName = packageName) propertySpecs.addAll(propertySpec) // Parses all specifications into properties @@ -137,7 +136,7 @@ internal class VssSpecificationSpecModel( val hasAmbiguousName = nestedClasses.contains(childSpecification.name) val uniquePackageName = if (hasAmbiguousName) "" else packageName - val childPropertySpec = createVssSpecificationSpecs(className, uniquePackageName, childSpecification) + val childPropertySpec = createVssNodeSpecs(className, uniquePackageName, childSpecification) propertySpecs.addAll(childPropertySpec) // Nested VssSpecification properties should be added as constructor parameters @@ -168,7 +167,7 @@ internal class VssSpecificationSpecModel( } } - val nodeSpecs = createVssNodeSpecs(childSpecifications) + val nodeSpecs = createVssNodeTreeSpecs(childSpecifications) propertySpecs.addAll(nodeSpecs) val className = ClassName(packageName, className) @@ -207,7 +206,7 @@ internal class VssSpecificationSpecModel( .defaultValue("%L()", defaultClassName) .build() - private fun createVssSpecificationSpecs( + private fun createVssNodeSpecs( className: String, packageName: String, specification: VssSpecificationSpecModel = this, @@ -259,7 +258,7 @@ internal class VssSpecificationSpecModel( return listOf(objectTypeSpec) } - private fun createVssNodeSpecs(childSpecifications: List): List { + private fun createVssNodeTreeSpecs(childSpecifications: List): List { fun createSetSpec(memberName: String, memberType: TypeName): PropertySpec { val specificationNamesJoined = childSpecifications.joinToString(", ") { it.variableName } @@ -291,7 +290,7 @@ internal class VssSpecificationSpecModel( val propertySpecs = mutableListOf() - val members = VssNode::class.declaredMemberProperties + val members = VssSpecification::class.declaredMemberProperties val setTypeName = Set::class.parameterizedBy(VssSpecification::class) val classTypeName = KClass::class.asClassName().parameterizedBy(STAR).copy(nullable = true) members.forEach { member -> From 4420cee73116245685382e299c708cbcdb87e3c1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mark=20Hu=CC=88sers?= Date: Wed, 28 Feb 2024 17:34:40 +0100 Subject: [PATCH 03/20] chore: Rename VssSpecification -> VssNode --- .../databroker/JavaDataBrokerEngine.java | 8 +-- .../kuksa/testapp/KuksaDataBrokerActivity.kt | 12 ++-- .../testapp/databroker/DataBrokerEngine.kt | 8 +-- .../databroker/KotlinDataBrokerEngine.kt | 8 +-- .../testapp/databroker/view/DataBrokerView.kt | 6 +- .../viewmodel/VssSpecificationsViewModel.kt | 14 ++-- .../org/eclipse/kuksa/DataBrokerConnection.kt | 20 +++--- .../org/eclipse/kuksa/PropertyListener.kt | 6 +- .../VssSpecificationCopyExtension.kt | 24 +++---- .../extension/VssSpecificationExtension.kt | 6 +- .../subscription/DataBrokerSubscriber.kt | 10 +-- .../SpecificationPropertyListener.kt | 4 +- .../FriendlyVssSpecificationListener.kt | 4 +- .../kuksa/vssSpecification/VssDriver.kt | 26 ++++---- .../kuksa/vssSpecification/VssVehicle.kt | 12 ++-- .../model/{VssSpecification.kt => VssNode.kt} | 66 +++++++++---------- .../eclipse/kuksa/vsscore/model/VssVehicle.kt | 14 ++-- .../parser/YamlDefinitionParser.kt | 4 +- .../spec/VssSpecificationSpecModel.kt | 10 +-- 19 files changed, 131 insertions(+), 131 deletions(-) rename vss-core/src/main/java/org/eclipse/kuksa/vsscore/model/{VssSpecification.kt => VssNode.kt} (70%) diff --git a/app/src/main/java/org/eclipse/kuksa/testapp/databroker/JavaDataBrokerEngine.java b/app/src/main/java/org/eclipse/kuksa/testapp/databroker/JavaDataBrokerEngine.java index 6935ac91..e186c7d0 100644 --- a/app/src/main/java/org/eclipse/kuksa/testapp/databroker/JavaDataBrokerEngine.java +++ b/app/src/main/java/org/eclipse/kuksa/testapp/databroker/JavaDataBrokerEngine.java @@ -36,7 +36,7 @@ import org.eclipse.kuksa.proto.v1.Types.Datapoint; import org.eclipse.kuksa.testapp.databroker.connection.DataBrokerConnectorFactory; import org.eclipse.kuksa.testapp.databroker.model.ConnectionInfo; -import org.eclipse.kuksa.vsscore.model.VssSpecification; +import org.eclipse.kuksa.vsscore.model.VssNode; import java.util.ArrayList; import java.util.HashSet; @@ -100,7 +100,7 @@ public void fetch(@NonNull Property property, @NonNull CoroutineCallback void fetch( + public void fetch( @NonNull T specification, @NonNull CoroutineCallback callback ) { @@ -134,7 +134,7 @@ public void subscribe(@NonNull Property property, @NonNull PropertyListener prop } @Override - public void subscribe( + public void subscribe( @NonNull T specification, @NonNull VssSpecificationListener specificationListener ) { @@ -152,7 +152,7 @@ public void subscribe( } @Override - public void unsubscribe( + public void unsubscribe( @NonNull T specification, @NonNull VssSpecificationListener specificationListener ) { diff --git a/app/src/main/kotlin/org/eclipse/kuksa/testapp/KuksaDataBrokerActivity.kt b/app/src/main/kotlin/org/eclipse/kuksa/testapp/KuksaDataBrokerActivity.kt index 52b48c0a..ba049e4a 100644 --- a/app/src/main/kotlin/org/eclipse/kuksa/testapp/KuksaDataBrokerActivity.kt +++ b/app/src/main/kotlin/org/eclipse/kuksa/testapp/KuksaDataBrokerActivity.kt @@ -58,7 +58,7 @@ import org.eclipse.kuksa.testapp.extension.TAG import org.eclipse.kuksa.testapp.preferences.ConnectionInfoRepository import org.eclipse.kuksa.testapp.ui.theme.KuksaAppAndroidTheme import org.eclipse.kuksa.vsscore.annotation.VssDefinition -import org.eclipse.kuksa.vsscore.model.VssSpecification +import org.eclipse.kuksa.vsscore.model.VssNode @VssDefinition class KuksaDataBrokerActivity : ComponentActivity() { @@ -109,8 +109,8 @@ class KuksaDataBrokerActivity : ComponentActivity() { } } - private val specificationListener = object : VssSpecificationListener { - override fun onSpecificationChanged(vssSpecification: VssSpecification) { + private val specificationListener = object : VssSpecificationListener { + override fun onSpecificationChanged(vssSpecification: VssNode) { outputViewModel.addOutputEntry("Updated specification: $vssSpecification") } @@ -305,11 +305,11 @@ class KuksaDataBrokerActivity : ComponentActivity() { ) } - private fun fetchSpecification(specification: VssSpecification) { + private fun fetchSpecification(specification: VssNode) { dataBrokerEngine.fetch( specification, - object : CoroutineCallback() { - override fun onSuccess(result: VssSpecification?) { + object : CoroutineCallback() { + override fun onSuccess(result: VssNode?) { Log.d(TAG, "Fetched specification: $result") outputViewModel.addOutputEntry("Fetched specification: $result") } diff --git a/app/src/main/kotlin/org/eclipse/kuksa/testapp/databroker/DataBrokerEngine.kt b/app/src/main/kotlin/org/eclipse/kuksa/testapp/databroker/DataBrokerEngine.kt index 22c21480..1648e333 100644 --- a/app/src/main/kotlin/org/eclipse/kuksa/testapp/databroker/DataBrokerEngine.kt +++ b/app/src/main/kotlin/org/eclipse/kuksa/testapp/databroker/DataBrokerEngine.kt @@ -30,7 +30,7 @@ import org.eclipse.kuksa.proto.v1.KuksaValV1.GetResponse import org.eclipse.kuksa.proto.v1.KuksaValV1.SetResponse import org.eclipse.kuksa.proto.v1.Types.Datapoint import org.eclipse.kuksa.testapp.databroker.model.ConnectionInfo -import org.eclipse.kuksa.vsscore.model.VssSpecification +import org.eclipse.kuksa.vsscore.model.VssNode @Suppress("complexity:TooManyFunctions") // required to test the api interface DataBrokerEngine { @@ -47,7 +47,7 @@ interface DataBrokerEngine { callback: CoroutineCallback, ) - fun fetch(specification: T, callback: CoroutineCallback) + fun fetch(specification: T, callback: CoroutineCallback) fun update( property: Property, @@ -59,12 +59,12 @@ interface DataBrokerEngine { fun unsubscribe(property: Property, propertyListener: PropertyListener) - fun subscribe( + fun subscribe( specification: T, specificationListener: VssSpecificationListener, ) - fun unsubscribe( + fun unsubscribe( specification: T, specificationListener: VssSpecificationListener, ) diff --git a/app/src/main/kotlin/org/eclipse/kuksa/testapp/databroker/KotlinDataBrokerEngine.kt b/app/src/main/kotlin/org/eclipse/kuksa/testapp/databroker/KotlinDataBrokerEngine.kt index 30731180..6d07fa6d 100644 --- a/app/src/main/kotlin/org/eclipse/kuksa/testapp/databroker/KotlinDataBrokerEngine.kt +++ b/app/src/main/kotlin/org/eclipse/kuksa/testapp/databroker/KotlinDataBrokerEngine.kt @@ -35,7 +35,7 @@ import org.eclipse.kuksa.proto.v1.KuksaValV1.SetResponse import org.eclipse.kuksa.proto.v1.Types.Datapoint import org.eclipse.kuksa.testapp.databroker.connection.DataBrokerConnectorFactory import org.eclipse.kuksa.testapp.databroker.model.ConnectionInfo -import org.eclipse.kuksa.vsscore.model.VssSpecification +import org.eclipse.kuksa.vsscore.model.VssNode @Suppress("complexity:TooManyFunctions") class KotlinDataBrokerEngine( @@ -85,7 +85,7 @@ class KotlinDataBrokerEngine( } } - override fun fetch(specification: T, callback: CoroutineCallback) { + override fun fetch(specification: T, callback: CoroutineCallback) { lifecycleScope.launch { try { val response = dataBrokerConnection?.fetch(specification) ?: return@launch @@ -115,7 +115,7 @@ class KotlinDataBrokerEngine( dataBrokerConnection?.unsubscribe(property, propertyListener) } - override fun subscribe( + override fun subscribe( specification: T, specificationListener: VssSpecificationListener, ) { @@ -124,7 +124,7 @@ class KotlinDataBrokerEngine( } } - override fun unsubscribe( + override fun unsubscribe( specification: T, specificationListener: VssSpecificationListener, ) { diff --git a/app/src/main/kotlin/org/eclipse/kuksa/testapp/databroker/view/DataBrokerView.kt b/app/src/main/kotlin/org/eclipse/kuksa/testapp/databroker/view/DataBrokerView.kt index 7e66978b..e6e475a8 100644 --- a/app/src/main/kotlin/org/eclipse/kuksa/testapp/databroker/view/DataBrokerView.kt +++ b/app/src/main/kotlin/org/eclipse/kuksa/testapp/databroker/view/DataBrokerView.kt @@ -91,7 +91,7 @@ import org.eclipse.kuksa.testapp.extension.compose.SimpleExposedDropdownMenuBox import org.eclipse.kuksa.testapp.preferences.ConnectionInfoRepository import org.eclipse.kuksa.testapp.ui.theme.KuksaAppAndroidTheme import org.eclipse.kuksa.vss.VssVehicle -import org.eclipse.kuksa.vsscore.model.VssSpecification +import org.eclipse.kuksa.vsscore.model.VssNode import java.time.format.DateTimeFormatter val SettingsMenuPadding = 16.dp @@ -239,8 +239,8 @@ fun DataBrokerSpecifications(viewModel: VssSpecificationsViewModel) { Column { Headline(name = "Specifications") - val adapter = object : SuggestionAdapter { - override fun toString(item: VssSpecification): String { + val adapter = object : SuggestionAdapter { + override fun toString(item: VssNode): String { return item.vssPath } } diff --git a/app/src/main/kotlin/org/eclipse/kuksa/testapp/databroker/viewmodel/VssSpecificationsViewModel.kt b/app/src/main/kotlin/org/eclipse/kuksa/testapp/databroker/viewmodel/VssSpecificationsViewModel.kt index f292f400..71c0e90e 100644 --- a/app/src/main/kotlin/org/eclipse/kuksa/testapp/databroker/viewmodel/VssSpecificationsViewModel.kt +++ b/app/src/main/kotlin/org/eclipse/kuksa/testapp/databroker/viewmodel/VssSpecificationsViewModel.kt @@ -26,15 +26,15 @@ import androidx.compose.runtime.mutableStateOf import androidx.compose.runtime.setValue import androidx.lifecycle.ViewModel import org.eclipse.kuksa.vss.VssVehicle -import org.eclipse.kuksa.vsscore.model.VssSpecification +import org.eclipse.kuksa.vsscore.model.VssNode import org.eclipse.kuksa.vsscore.model.heritage class VssSpecificationsViewModel : ViewModel() { - var onGetSpecification: (specification: VssSpecification) -> Unit = { } - var onSubscribeSpecification: (specification: VssSpecification) -> Unit = { } - var onUnsubscribeSpecification: (specification: VssSpecification) -> Unit = { } + var onGetSpecification: (specification: VssNode) -> Unit = { } + var onSubscribeSpecification: (specification: VssNode) -> Unit = { } + var onUnsubscribeSpecification: (specification: VssNode) -> Unit = { } - var subscribedSpecifications = mutableStateListOf() + var subscribedSpecifications = mutableStateListOf() val isSubscribed by derivedStateOf { subscribedSpecifications.contains(specification) @@ -43,10 +43,10 @@ class VssSpecificationsViewModel : ViewModel() { private val vssVehicle = VssVehicle() val specifications = listOf(vssVehicle) + vssVehicle.heritage - var specification: VssSpecification by mutableStateOf(vssVehicle) + var specification: VssNode by mutableStateOf(vssVehicle) private set - fun updateSpecification(specification: VssSpecification) { + fun updateSpecification(specification: VssNode) { this.specification = specification } } diff --git a/kuksa-sdk/src/main/kotlin/org/eclipse/kuksa/DataBrokerConnection.kt b/kuksa-sdk/src/main/kotlin/org/eclipse/kuksa/DataBrokerConnection.kt index a5b8328e..20884620 100644 --- a/kuksa-sdk/src/main/kotlin/org/eclipse/kuksa/DataBrokerConnection.kt +++ b/kuksa-sdk/src/main/kotlin/org/eclipse/kuksa/DataBrokerConnection.kt @@ -38,7 +38,7 @@ import org.eclipse.kuksa.proto.v1.Types.Datapoint import org.eclipse.kuksa.proto.v1.Types.Field import org.eclipse.kuksa.subscription.DataBrokerSubscriber import org.eclipse.kuksa.vsscore.model.VssLeaf -import org.eclipse.kuksa.vsscore.model.VssSpecification +import org.eclipse.kuksa.vsscore.model.VssNode import org.eclipse.kuksa.vsscore.model.heritage import org.eclipse.kuksa.vsscore.model.vssProperties import kotlin.properties.Delegates @@ -112,8 +112,8 @@ class DataBrokerConnection internal constructor( } /** - * Subscribes to the specified [VssSpecification] with the provided [VssSpecificationListener]. Only a [VssLeaf] - * can be subscribed because they have an actual value. When provided with any parent [VssSpecification] then this + * Subscribes to the specified [VssNode] with the provided [VssSpecificationListener]. Only a [VssLeaf] + * can be subscribed because they have an actual value. When provided with any parent [VssNode] then this * [subscribe] method will find all [VssLeaf] children and subscribes them instead. Once subscribed the * application will be notified about any changes to every subscribed [VssLeaf]. The [fields] can be used to * subscribe to different information of the [specification]. The default for the [fields] parameter is a list with @@ -122,7 +122,7 @@ class DataBrokerConnection internal constructor( * @throws DataBrokerException in case the connection to the DataBroker is no longer active */ @JvmOverloads - fun subscribe( + fun subscribe( specification: T, fields: Collection = listOf(Field.FIELD_VALUE), listener: VssSpecificationListener, @@ -135,7 +135,7 @@ class DataBrokerConnection internal constructor( /** * Unsubscribes the [listener] from updates of the specified [fields] and [specification]. */ - fun unsubscribe( + fun unsubscribe( specification: T, fields: Collection = listOf(Field.FIELD_VALUE), listener: VssSpecificationListener, @@ -156,7 +156,7 @@ class DataBrokerConnection internal constructor( } /** - * Retrieves the [VssSpecification] and returns it. The retrieved [VssSpecification] + * Retrieves the [VssNode] and returns it. The retrieved [VssNode] * is of the same type as the inputted one. All underlying heirs are changed to reflect the data broker state. * The [fields] can be used to subscribe to different information of the [specification]. The default for the * [fields] parameter is a list with a single [Types.Field.FIELD_VALUE] entry. @@ -165,7 +165,7 @@ class DataBrokerConnection internal constructor( */ @Suppress("exceptions:TooGenericExceptionCaught") // Handling is bundled together @JvmOverloads - suspend fun fetch( + suspend fun fetch( specification: T, fields: Collection = listOf(Field.FIELD_VALUE), ): T { @@ -211,17 +211,17 @@ class DataBrokerConnection internal constructor( /** * Only a [VssLeaf] can be updated because they have an actual value. When provided with any parent - * [VssSpecification] then this [update] method will find all [VssLeaf] children and updates their corresponding + * [VssNode] then this [update] method will find all [VssLeaf] children and updates their corresponding * [fields] instead. * Compared to [update] with only one [Property] and [Datapoint], here multiple [SetResponse] will be returned - * because a [VssSpecification] may consists of multiple values which may need to be updated. + * because a [VssNode] may consists of multiple values which may need to be updated. * * @throws DataBrokerException in case the connection to the DataBroker is no longer active * @throws IllegalArgumentException if the [VssLeaf] could not be converted to a [Datapoint]. */ @JvmOverloads suspend fun update( - vssSpecification: VssSpecification, + vssSpecification: VssNode, fields: Collection = listOf(Field.FIELD_VALUE), ): Collection { val responses = mutableListOf() diff --git a/kuksa-sdk/src/main/kotlin/org/eclipse/kuksa/PropertyListener.kt b/kuksa-sdk/src/main/kotlin/org/eclipse/kuksa/PropertyListener.kt index 617eb786..fc59de37 100644 --- a/kuksa-sdk/src/main/kotlin/org/eclipse/kuksa/PropertyListener.kt +++ b/kuksa-sdk/src/main/kotlin/org/eclipse/kuksa/PropertyListener.kt @@ -21,7 +21,7 @@ package org.eclipse.kuksa import org.eclipse.kuksa.pattern.listener.Listener import org.eclipse.kuksa.proto.v1.KuksaValV1 -import org.eclipse.kuksa.vsscore.model.VssSpecification +import org.eclipse.kuksa.vsscore.model.VssNode /** * The Listener is used to notify about changes to subscribed [org.eclipse.kuksa.model.Property]. When registering the @@ -41,10 +41,10 @@ interface PropertyListener : Listener { } /** - * The Listener is used to notify about subscribed [VssSpecification]. If a [VssSpecification] has children + * The Listener is used to notify about subscribed [VssNode]. If a [VssNode] has children * then [onSpecificationChanged] will be called on every value change for every children. */ -interface VssSpecificationListener { +interface VssSpecificationListener { /** * Will be triggered with the [vssSpecification] when the underlying vssPath changed it's value or to inform about * the initial state. diff --git a/kuksa-sdk/src/main/kotlin/org/eclipse/kuksa/extension/VssSpecificationCopyExtension.kt b/kuksa-sdk/src/main/kotlin/org/eclipse/kuksa/extension/VssSpecificationCopyExtension.kt index 9d28e52f..eeaf7fb5 100644 --- a/kuksa-sdk/src/main/kotlin/org/eclipse/kuksa/extension/VssSpecificationCopyExtension.kt +++ b/kuksa-sdk/src/main/kotlin/org/eclipse/kuksa/extension/VssSpecificationCopyExtension.kt @@ -23,14 +23,14 @@ import org.eclipse.kuksa.proto.v1.Types import org.eclipse.kuksa.proto.v1.Types.Datapoint import org.eclipse.kuksa.proto.v1.Types.Datapoint.ValueCase.* import org.eclipse.kuksa.vsscore.model.VssLeaf -import org.eclipse.kuksa.vsscore.model.VssSpecification +import org.eclipse.kuksa.vsscore.model.VssNode import org.eclipse.kuksa.vsscore.model.findHeritageLine import org.eclipse.kuksa.vsscore.model.heritage import org.eclipse.kuksa.vsscore.model.variableName import kotlin.reflect.full.memberProperties /** - * Creates a copy of the [VssSpecification] where the whole [VssSpecification.findHeritageLine] is replaced + * Creates a copy of the [VssNode] where the whole [VssNode.findHeritageLine] is replaced * with modified heirs. * * ### Example: @@ -40,7 +40,7 @@ import kotlin.reflect.full.memberProperties * * A deep copy is necessary for a nested history tree with at least two generations. The VssWindowChildLockEngaged * is replaced inside VssCabin where this again is replaced inside VssVehicle. Use the [generation] to start copying - * from the [VssSpecification] to the [deepCopy]. Returns a copy where every heir in the given [changedHeritage] is + * from the [VssNode] to the [deepCopy]. Returns a copy where every heir in the given [changedHeritage] is * replaced with another copy. * * @throws [IllegalArgumentException] if the copied types do not match. This can happen if the [heritage] is not @@ -50,7 +50,7 @@ import kotlin.reflect.full.memberProperties // The suggested method to improve the performance can't be used here because we are already working with a full array. // https://detekt.dev/docs/rules/performance/ @Suppress("performance:SpreadOperator") -fun T.deepCopy(generation: Int = 0, vararg changedHeritage: VssSpecification): T { +fun T.deepCopy(generation: Int = 0, vararg changedHeritage: VssNode): T { if (generation == changedHeritage.size) { // Reached the end, use the changed VssProperty return this } @@ -137,21 +137,21 @@ fun VssLeaf.copy(value: T): VssLeaf { } /** - * Creates a copy of the [VssSpecification] where the heir with a matching [vssPath] is replaced with the + * Creates a copy of the [VssNode] where the heir with a matching [vssPath] is replaced with the * [updatedValue]. * - * @param consideredHeritage the heritage of the [VssSpecification] which is considered for searching. The default - * will always generate the up to date heritage of the current [VssSpecification]. For performance reason it may make + * @param consideredHeritage the heritage of the [VssNode] which is considered for searching. The default + * will always generate the up to date heritage of the current [VssNode]. For performance reason it may make * sense to cache the input and reuse the [Collection] here. * * @throws [IllegalArgumentException] if the copied types do not match. * @throws [NoSuchElementException] if no copy method was found for the class. */ @Suppress("UNCHECKED_CAST") -fun T.copy( +fun T.copy( vssPath: String, updatedValue: Datapoint, - consideredHeritage: Collection = heritage, + consideredHeritage: Collection = heritage, ): T { val vssSpecifications = consideredHeritage + this val vssProperty = vssSpecifications @@ -169,13 +169,13 @@ fun T.copy( // region Operators /** - * Convenience operator for [deepCopy] with a [VssSpecification]. It will return the [VssSpecification] with the updated - * [VssSpecification]. + * Convenience operator for [deepCopy] with a [VssNode]. It will return the [VssNode] with the updated + * [VssNode]. * * @throws [IllegalArgumentException] if the copied types do not match. * @throws [NoSuchElementException] if no copy method was found for the class. */ -operator fun T.invoke(vararg property: VssSpecification): T { +operator fun T.invoke(vararg property: VssNode): T { return deepCopy(0, *property) } diff --git a/kuksa-sdk/src/main/kotlin/org/eclipse/kuksa/extension/VssSpecificationExtension.kt b/kuksa-sdk/src/main/kotlin/org/eclipse/kuksa/extension/VssSpecificationExtension.kt index 6e8496ea..a4d2bccd 100644 --- a/kuksa-sdk/src/main/kotlin/org/eclipse/kuksa/extension/VssSpecificationExtension.kt +++ b/kuksa-sdk/src/main/kotlin/org/eclipse/kuksa/extension/VssSpecificationExtension.kt @@ -21,13 +21,13 @@ package org.eclipse.kuksa.extension import org.eclipse.kuksa.model.Property import org.eclipse.kuksa.proto.v1.Types import org.eclipse.kuksa.vsscore.model.VssLeaf -import org.eclipse.kuksa.vsscore.model.VssSpecification +import org.eclipse.kuksa.vsscore.model.VssNode import org.eclipse.kuksa.vsscore.model.vssProperties /** - * Finds all [VssLeaf] heirs for the [VssSpecification] and converts them into a collection of [Property]. + * Finds all [VssLeaf] heirs for the [VssNode] and converts them into a collection of [Property]. */ -fun VssSpecification.createProperties( +fun VssNode.createProperties( vararg fields: Types.Field = arrayOf(Types.Field.FIELD_VALUE), ): Collection { return vssProperties diff --git a/kuksa-sdk/src/main/kotlin/org/eclipse/kuksa/subscription/DataBrokerSubscriber.kt b/kuksa-sdk/src/main/kotlin/org/eclipse/kuksa/subscription/DataBrokerSubscriber.kt index 306942a7..8c38a0cc 100644 --- a/kuksa-sdk/src/main/kotlin/org/eclipse/kuksa/subscription/DataBrokerSubscriber.kt +++ b/kuksa-sdk/src/main/kotlin/org/eclipse/kuksa/subscription/DataBrokerSubscriber.kt @@ -28,7 +28,7 @@ import org.eclipse.kuksa.extension.TAG import org.eclipse.kuksa.proto.v1.Types import org.eclipse.kuksa.proto.v1.Types.Field import org.eclipse.kuksa.vsscore.model.VssLeaf -import org.eclipse.kuksa.vsscore.model.VssSpecification +import org.eclipse.kuksa.vsscore.model.VssNode /** * Creates [Subscription]s to the DataBroker to get notified about changes on the underlying vssPaths and fields. @@ -76,8 +76,8 @@ internal class DataBrokerSubscriber(private val dataBrokerTransporter: DataBroke } /** - * Subscribes to the specified [VssSpecification] with the provided [VssSpecificationListener]. Only a [VssLeaf] - * can be subscribed because they have an actual value. When provided with any parent [VssSpecification] then this + * Subscribes to the specified [VssNode] with the provided [VssSpecificationListener]. Only a [VssLeaf] + * can be subscribed because they have an actual value. When provided with any parent [VssNode] then this * [subscribe] method will find all [VssLeaf] children and subscribes them instead. Once subscribed the * application will be notified about any changes to every subscribed [VssLeaf]. The [field] can be used to * subscribe to different information of the [specification]. The default for the [field] parameter is a single @@ -85,7 +85,7 @@ internal class DataBrokerSubscriber(private val dataBrokerTransporter: DataBroke * * @throws DataBrokerException in case the connection to the DataBroker is no longer active */ - fun subscribe( + fun subscribe( specification: T, field: Field = Field.FIELD_VALUE, listener: VssSpecificationListener, @@ -102,7 +102,7 @@ internal class DataBrokerSubscriber(private val dataBrokerTransporter: DataBroke * canceled and removed. Gracefully ignores invalid input, e.g. when a [specification] and [field] of a * non-subscribed property is provided. */ - fun unsubscribe( + fun unsubscribe( specification: T, field: Field = Field.FIELD_VALUE, listener: VssSpecificationListener, diff --git a/kuksa-sdk/src/main/kotlin/org/eclipse/kuksa/subscription/SpecificationPropertyListener.kt b/kuksa-sdk/src/main/kotlin/org/eclipse/kuksa/subscription/SpecificationPropertyListener.kt index b93dfe65..5f46bd4a 100644 --- a/kuksa-sdk/src/main/kotlin/org/eclipse/kuksa/subscription/SpecificationPropertyListener.kt +++ b/kuksa-sdk/src/main/kotlin/org/eclipse/kuksa/subscription/SpecificationPropertyListener.kt @@ -23,9 +23,9 @@ import org.eclipse.kuksa.PropertyListener import org.eclipse.kuksa.VssSpecificationListener import org.eclipse.kuksa.extension.copy import org.eclipse.kuksa.proto.v1.KuksaValV1 -import org.eclipse.kuksa.vsscore.model.VssSpecification +import org.eclipse.kuksa.vsscore.model.VssNode -internal class SpecificationPropertyListener( +internal class SpecificationPropertyListener( specification: T, private val listener: VssSpecificationListener, ) : PropertyListener { diff --git a/kuksa-sdk/src/test/kotlin/org/eclipse/kuksa/mocking/FriendlyVssSpecificationListener.kt b/kuksa-sdk/src/test/kotlin/org/eclipse/kuksa/mocking/FriendlyVssSpecificationListener.kt index e9a45990..1f2009b2 100644 --- a/kuksa-sdk/src/test/kotlin/org/eclipse/kuksa/mocking/FriendlyVssSpecificationListener.kt +++ b/kuksa-sdk/src/test/kotlin/org/eclipse/kuksa/mocking/FriendlyVssSpecificationListener.kt @@ -20,9 +20,9 @@ package org.eclipse.kuksa.mocking import org.eclipse.kuksa.VssSpecificationListener -import org.eclipse.kuksa.vsscore.model.VssSpecification +import org.eclipse.kuksa.vsscore.model.VssNode -class FriendlyVssSpecificationListener : VssSpecificationListener { +class FriendlyVssSpecificationListener : VssSpecificationListener { val updatedSpecifications = mutableListOf() val errors = mutableListOf() override fun onSpecificationChanged(vssSpecification: T) { diff --git a/kuksa-sdk/src/test/kotlin/org/eclipse/kuksa/vssSpecification/VssDriver.kt b/kuksa-sdk/src/test/kotlin/org/eclipse/kuksa/vssSpecification/VssDriver.kt index 9b9e447e..83c3102a 100644 --- a/kuksa-sdk/src/test/kotlin/org/eclipse/kuksa/vssSpecification/VssDriver.kt +++ b/kuksa-sdk/src/test/kotlin/org/eclipse/kuksa/vssSpecification/VssDriver.kt @@ -20,7 +20,7 @@ package org.eclipse.kuksa.vssSpecification import org.eclipse.kuksa.vsscore.model.VssLeaf -import org.eclipse.kuksa.vsscore.model.VssSpecification +import org.eclipse.kuksa.vsscore.model.VssNode import kotlin.reflect.KClass data class VssDriver @JvmOverloads constructor( @@ -31,7 +31,7 @@ data class VssDriver @JvmOverloads constructor( val identifier: VssIdentifier = VssIdentifier(), val isEyesOnRoad: VssIsEyesOnRoad = VssIsEyesOnRoad(), val isHandsOnWheel: VssIsHandsOnWheel = VssIsHandsOnWheel(), -) : VssSpecification { +) : VssNode { override val comment: String get() = "" @@ -47,7 +47,7 @@ data class VssDriver @JvmOverloads constructor( override val vssPath: String get() = "Vehicle.Driver" - override val children: Set + override val children: Set get() = setOf( attentiveProbability, distractionLevel, @@ -79,7 +79,7 @@ data class VssDriver @JvmOverloads constructor( override val vssPath: String get() = "Vehicle.Driver.HeartRate" - override val children: Set + override val children: Set get() = setOf() override val parentClass: KClass<*> @@ -105,7 +105,7 @@ data class VssAttentiveProbability @JvmOverloads constructor( override val vssPath: String get() = "Vehicle.Driver.AttentiveProbability" - override val children: Set + override val children: Set get() = setOf() override val parentClass: KClass<*> @@ -130,7 +130,7 @@ data class VssDistractionLevel @JvmOverloads constructor( override val vssPath: String get() = "Vehicle.Driver.DistractionLevel" - override val children: Set + override val children: Set get() = setOf() override val parentClass: KClass<*> @@ -155,7 +155,7 @@ data class VssFatigueLevel @JvmOverloads constructor( override val vssPath: String get() = "Vehicle.Driver.FatigueLevel" - override val children: Set + override val children: Set get() = setOf() override val parentClass: KClass<*> @@ -165,7 +165,7 @@ data class VssFatigueLevel @JvmOverloads constructor( data class VssIdentifier @JvmOverloads constructor( val issuer: VssIssuer = VssIssuer(), val subject: VssSubject = VssSubject(), -) : VssSpecification { +) : VssNode { override val comment: String get() = "" @@ -181,7 +181,7 @@ data class VssIdentifier @JvmOverloads constructor( override val vssPath: String get() = "Vehicle.Driver.Identifier" - override val children: Set + override val children: Set get() = setOf(issuer, subject) override val parentClass: KClass<*> @@ -207,7 +207,7 @@ data class VssIssuer @JvmOverloads constructor( override val vssPath: String get() = "Vehicle.Driver.Identifier.Issuer" - override val children: Set + override val children: Set get() = setOf() override val parentClass: KClass<*> @@ -232,7 +232,7 @@ data class VssSubject @JvmOverloads constructor( override val vssPath: String get() = "Vehicle.Driver.Identifier.Subject" - override val children: Set + override val children: Set get() = setOf() override val parentClass: KClass<*> @@ -257,7 +257,7 @@ data class VssIsEyesOnRoad @JvmOverloads constructor( override val vssPath: String get() = "Vehicle.Driver.IsEyesOnRoad" - override val children: Set + override val children: Set get() = setOf() override val parentClass: KClass<*> @@ -282,7 +282,7 @@ data class VssIsHandsOnWheel @JvmOverloads constructor( override val vssPath: String get() = "Vehicle.Driver.IsHandsOnWheel" - override val children: Set + override val children: Set get() = setOf() override val parentClass: KClass<*> diff --git a/kuksa-sdk/src/test/kotlin/org/eclipse/kuksa/vssSpecification/VssVehicle.kt b/kuksa-sdk/src/test/kotlin/org/eclipse/kuksa/vssSpecification/VssVehicle.kt index a3431570..1dbd3172 100644 --- a/kuksa-sdk/src/test/kotlin/org/eclipse/kuksa/vssSpecification/VssVehicle.kt +++ b/kuksa-sdk/src/test/kotlin/org/eclipse/kuksa/vssSpecification/VssVehicle.kt @@ -20,7 +20,7 @@ package org.eclipse.kuksa.vssSpecification import org.eclipse.kuksa.vsscore.model.VssLeaf -import org.eclipse.kuksa.vsscore.model.VssSpecification +import org.eclipse.kuksa.vsscore.model.VssNode import kotlin.reflect.KClass data class VssVehicle( @@ -32,8 +32,8 @@ data class VssVehicle( override val description: String = "High-level vehicle data.", override val type: String = "branch", override val comment: String = "", -) : VssSpecification { - override val children: Set +) : VssNode { + override val children: Set get() = setOf(driver, passenger, body) } @@ -43,7 +43,7 @@ data class VssBody( override val description: String = "All body components.", override val type: String = "branch", override val comment: String = "", -) : VssSpecification { +) : VssNode { override val parentClass: KClass<*> get() = VssVehicle::class } @@ -55,8 +55,8 @@ data class VssPassenger( override val description: String = "Passenger data", override val type: String = "branch", override val comment: String = "", -) : VssSpecification { - override val children: Set +) : VssNode { + override val children: Set get() = setOf(heartRate) override val parentClass: KClass<*> get() = VssVehicle::class diff --git a/vss-core/src/main/java/org/eclipse/kuksa/vsscore/model/VssSpecification.kt b/vss-core/src/main/java/org/eclipse/kuksa/vsscore/model/VssNode.kt similarity index 70% rename from vss-core/src/main/java/org/eclipse/kuksa/vsscore/model/VssSpecification.kt rename to vss-core/src/main/java/org/eclipse/kuksa/vsscore/model/VssNode.kt index 7acd8f38..3a790065 100644 --- a/vss-core/src/main/java/org/eclipse/kuksa/vsscore/model/VssSpecification.kt +++ b/vss-core/src/main/java/org/eclipse/kuksa/vsscore/model/VssNode.kt @@ -24,10 +24,10 @@ import kotlin.reflect.KClass import kotlin.reflect.full.declaredMemberProperties /** - * Represents a node inside a VSS specification file. it represents the most common properties of a VSS specification. + * Represents a node inside a VSS file. it represents the most common properties. * The [uuid] is a mandatory field and should never be empty. */ -interface VssSpecification { +interface VssNode { val uuid: String val vssPath: String val description: String @@ -37,7 +37,7 @@ interface VssSpecification { /** * A collection of all initialized children. */ - val children: Set + val children: Set get() = emptySet() /** @@ -48,23 +48,23 @@ interface VssSpecification { } /** - * Some [VssSpecification] may have an additional [value] property. These are children which are not parents. + * Some [VssNode] may have an additional [value] property. These are children which are not parents. */ -interface VssLeaf : VssSpecification { +interface VssLeaf : VssNode { val value: T } /** - * Splits the [VssSpecification.vssPath] into its parts. + * Splits the [VssNode.vssPath] into its parts. */ -val VssSpecification.vssPathComponents: List +val VssNode.vssPathComponents: List get() = vssPath.split(".") /** - * Generates a heritage line with the [VssSpecification.vssPath] from the most known parent. + * Generates a heritage line with the [VssNode.vssPath] from the most known parent. * E.g. "Vehicle.OBD.Catalyst" -> [Vehicle, Vehicle.OBD, Vehicle.OBD.Catalyst] */ -val VssSpecification.vssPathHeritageLine: List +val VssNode.vssPathHeritageLine: List get() { val components = vssPathComponents return components.foldIndexed(emptyList()) { index, accumulation, _ -> @@ -74,21 +74,21 @@ val VssSpecification.vssPathHeritageLine: List } /** - * Parses a name from the [VssSpecification.vssPath]. + * Parses a name from the [VssNode.vssPath]. */ -val VssSpecification.name: String +val VssNode.name: String get() = vssPath.substringAfterLast(".") /** - * Return the parent [VssSpecification.vssPath]. + * Return the parent [VssNode.vssPath]. */ -val VssSpecification.parentVssPath: String +val VssNode.parentVssPath: String get() = vssPath.substringBeforeLast(".", "") /** - * Returns the parent key depending on the [VssSpecification.vssPath]. + * Returns the parent key depending on the [VssNode.vssPath]. */ -val VssSpecification.parentKey: String +val VssNode.parentKey: String get() { val keys = vssPathComponents if (keys.size < 2) return "" @@ -99,7 +99,7 @@ val VssSpecification.parentKey: String /** * Similar to the [variableName] but for the parent and does not lowercase the [name] wherever necessary. */ -val VssSpecification.parentClassName: String +val VssNode.parentClassName: String get() { if (parentKey.isEmpty()) return "" @@ -109,13 +109,13 @@ val VssSpecification.parentClassName: String /** * Iterates through all nested children which also may have children and aggregates them into one big collection. */ -val VssSpecification.heritage: Collection +val VssNode.heritage: Collection get() = children.toList() + children.flatMap { it.heritage } /** - * Finds the latest generation in the form of [VssLeaf] for the current [VssSpecification]. + * Finds the latest generation in the form of [VssLeaf] for the current [VssNode]. */ -val VssSpecification.vssProperties: Collection> +val VssNode.vssProperties: Collection> get() = heritage .ifEmpty { setOf(this) } .filterIsInstance>() @@ -124,7 +124,7 @@ val VssSpecification.vssProperties: Collection> * Uses the [variablePrefix] to generate a unique variable name. The first character is at least lowercased. * If the [name] is something like "ABS" then it is converted to "abs" instead of "aBS". */ -val VssSpecification.variableName: String // Fixes duplicates e.g. type as variable and nested type +val VssNode.variableName: String // Fixes duplicates e.g. type as variable and nested type get() { val fullName = (variablePrefix + name).toCamelCase @@ -134,7 +134,7 @@ val VssSpecification.variableName: String // Fixes duplicates e.g. type as varia /** * Similar to the [variableName] but does not lowercase the [name] wherever necessary. */ -val VssSpecification.className: String +val VssNode.className: String get() { return (classNamePrefix + name).toCamelCase.replaceFirstChar { it.uppercase() } } @@ -142,15 +142,15 @@ val VssSpecification.className: String /** * Used in case of conflicted naming with child properties. */ -private val VssSpecification.variablePrefix: String +private val VssNode.variablePrefix: String get() = if (isVariableOccupied) classNamePrefix else "" /** * True if the [name] clashes with a property name. */ -private val VssSpecification.isVariableOccupied: Boolean +private val VssNode.isVariableOccupied: Boolean get() { - val declaredMemberProperties = VssSpecification::class.declaredMemberProperties + val declaredMemberProperties = VssNode::class.declaredMemberProperties return declaredMemberProperties.find { member -> member.name.equals(name, true) } != null @@ -161,16 +161,16 @@ private val classNamePrefix: String /** * Creates an inheritance line to the given [heir]. Similar to [vssPathHeritageLine] but the other way around. It - * returns a [Collection] of the full heritage line in the form of [VssSpecification]. + * returns a [Collection] of the full heritage line in the form of [VssNode]. * * ### Hint - * The given heir is only used to find the heir inside the [VssSpecification]. It may differ from the one which is + * The given heir is only used to find the heir inside the [VssNode]. It may differ from the one which is * returned. If you want the heritage replaced by the given [heir] parameter then use the [isReplacingHeir] parameter. */ -fun VssSpecification.findHeritageLine( - heir: VssSpecification, +fun VssNode.findHeritageLine( + heir: VssNode, isReplacingHeir: Boolean = false, -): Collection { +): Collection { val specificationKeys = heir.vssPathHeritageLine val heritageLine = heritage.filter { child -> specificationKeys.contains(child.vssPath) @@ -185,9 +185,9 @@ fun VssSpecification.findHeritageLine( } /** - * Finds the given [property] inside the current [VssSpecification]. + * Finds the given [property] inside the current [VssNode]. */ -fun , V : Any> VssSpecification.findProperty(property: VssLeaf): VssLeaf { +fun , V : Any> VssNode.findProperty(property: VssLeaf): VssLeaf { return heritage .filterIsInstance>() .first { it.uuid == property.uuid } @@ -195,9 +195,9 @@ fun , V : Any> VssSpecification.findProperty(property: VssLeaf /** * Finds all [VssLeaf] which matches the given [KClass.simpleName]. This is useful when multiple nested objects - * with the same Name exists but are pretty much the same besides the [VssSpecification.vssPath] etc. + * with the same Name exists but are pretty much the same besides the [VssNode.vssPath] etc. */ -fun , V : Any> VssSpecification.findProperties(type: KClass): Map> { +fun , V : Any> VssNode.findProperties(type: KClass): Map> { return heritage .filterIsInstance>() .filter { it::class.simpleName == type.simpleName } diff --git a/vss-core/src/test/java/org/eclipse/kuksa/vsscore/model/VssVehicle.kt b/vss-core/src/test/java/org/eclipse/kuksa/vsscore/model/VssVehicle.kt index 2cc80336..2e3d7f35 100644 --- a/vss-core/src/test/java/org/eclipse/kuksa/vsscore/model/VssVehicle.kt +++ b/vss-core/src/test/java/org/eclipse/kuksa/vsscore/model/VssVehicle.kt @@ -30,8 +30,8 @@ data class VssVehicle( override val description: String = "High-level vehicle data.", override val type: String = "branch", override val comment: String = "", -) : VssSpecification { - override val children: Set +) : VssNode { + override val children: Set get() = setOf(driver, passenger, body) } @@ -41,7 +41,7 @@ data class VssBody( override val description: String = "All body components.", override val type: String = "branch", override val comment: String = "", -) : VssSpecification { +) : VssNode { override val parentClass: KClass<*> get() = VssVehicle::class } @@ -53,8 +53,8 @@ data class VssDriver( override val description: String = "Driver data.", override val type: String = "branch", override val comment: String = "", -) : VssSpecification { - override val children: Set +) : VssNode { + override val children: Set get() = setOf(heartRate) override val parentClass: KClass<*> get() = VssVehicle::class @@ -79,8 +79,8 @@ data class VssPassenger( override val description: String = "Passenger data", override val type: String = "branch", override val comment: String = "", -) : VssSpecification { - override val children: Set +) : VssNode { + override val children: Set get() = setOf(heartRate) override val parentClass: KClass<*> get() = VssVehicle::class diff --git a/vss-processor/src/main/kotlin/org/eclipse/kuksa/vssprocessor/parser/YamlDefinitionParser.kt b/vss-processor/src/main/kotlin/org/eclipse/kuksa/vssprocessor/parser/YamlDefinitionParser.kt index c7aad65f..c4fd3778 100644 --- a/vss-processor/src/main/kotlin/org/eclipse/kuksa/vssprocessor/parser/YamlDefinitionParser.kt +++ b/vss-processor/src/main/kotlin/org/eclipse/kuksa/vssprocessor/parser/YamlDefinitionParser.kt @@ -19,7 +19,7 @@ package org.eclipse.kuksa.vssprocessor.parser -import org.eclipse.kuksa.vsscore.model.VssSpecification +import org.eclipse.kuksa.vsscore.model.VssNode import org.eclipse.kuksa.vssprocessor.spec.VssSpecificationSpecModel import java.io.File import kotlin.reflect.KMutableProperty @@ -102,7 +102,7 @@ internal class YamlDefinitionParser : VssDefinitionParser { * @param fields to set via reflection. Pair. * @param remapNames which can be used if the propertyName does not match with the input name */ -private fun VssSpecification.setFields( +private fun VssNode.setFields( fields: List>, remapNames: Map = emptyMap(), ) { diff --git a/vss-processor/src/main/kotlin/org/eclipse/kuksa/vssprocessor/spec/VssSpecificationSpecModel.kt b/vss-processor/src/main/kotlin/org/eclipse/kuksa/vssprocessor/spec/VssSpecificationSpecModel.kt index 2eb86cac..c6e9c863 100644 --- a/vss-processor/src/main/kotlin/org/eclipse/kuksa/vssprocessor/spec/VssSpecificationSpecModel.kt +++ b/vss-processor/src/main/kotlin/org/eclipse/kuksa/vssprocessor/spec/VssSpecificationSpecModel.kt @@ -33,7 +33,7 @@ import com.squareup.kotlinpoet.TypeSpec import com.squareup.kotlinpoet.asClassName import com.squareup.kotlinpoet.asTypeName import org.eclipse.kuksa.vsscore.model.VssLeaf -import org.eclipse.kuksa.vsscore.model.VssSpecification +import org.eclipse.kuksa.vsscore.model.VssNode import org.eclipse.kuksa.vsscore.model.className import org.eclipse.kuksa.vsscore.model.name import org.eclipse.kuksa.vsscore.model.parentClassName @@ -52,7 +52,7 @@ internal class VssSpecificationSpecModel( override var type: String = "", override var comment: String = "", @Suppress("MemberVisibilityCanBePrivate") var datatype: String = "", -) : VssSpecification, SpecModel { +) : VssNode, SpecModel { var logger: KSPLogger? = null private val datatypeProperty: TypeName @@ -109,7 +109,7 @@ internal class VssSpecificationSpecModel( val constructorBuilder = FunSpec.constructorBuilder() .addAnnotation(JvmOverloads::class) val propertySpecs = mutableListOf() - val superInterfaces = mutableSetOf(VssSpecification::class.asTypeName()) + val superInterfaces = mutableSetOf(VssNode::class.asTypeName()) // The last element in the chain should have a value like "isLocked". if (childSpecifications.isEmpty()) { @@ -212,9 +212,9 @@ internal class VssSpecificationSpecModel( specification: VssSpecificationSpecModel = this, ): List { val propertySpecs = mutableListOf() - val members = VssSpecification::class.declaredMemberProperties + val members = VssNode::class.declaredMemberProperties - fun createInterfaceDataTypeSpec(member: KProperty1): PropertySpec { + fun createInterfaceDataTypeSpec(member: KProperty1): PropertySpec { val memberName = member.name val memberType = member.returnType.asTypeName() val initialValue = member.get(specification) ?: "" From 819c648d0ad596a853f67685cbf039d9fb5c5dcf Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mark=20Hu=CC=88sers?= Date: Thu, 29 Feb 2024 11:15:00 +0100 Subject: [PATCH 04/20] chore: Adapt generator for merged VssSpecification + VssNode The VssSpecification (renamed to VssNode) now also has additional properties defined. The property type was not checked before when generating the vss node attributes like the UUID. This resulted into a duplicated generation of the "child" + "parent" properties. --- .../spec/VssSpecificationSpecModel.kt | 27 +++++++++++-------- 1 file changed, 16 insertions(+), 11 deletions(-) diff --git a/vss-processor/src/main/kotlin/org/eclipse/kuksa/vssprocessor/spec/VssSpecificationSpecModel.kt b/vss-processor/src/main/kotlin/org/eclipse/kuksa/vssprocessor/spec/VssSpecificationSpecModel.kt index c6e9c863..621505d3 100644 --- a/vss-processor/src/main/kotlin/org/eclipse/kuksa/vssprocessor/spec/VssSpecificationSpecModel.kt +++ b/vss-processor/src/main/kotlin/org/eclipse/kuksa/vssprocessor/spec/VssSpecificationSpecModel.kt @@ -55,6 +55,10 @@ internal class VssSpecificationSpecModel( ) : VssNode, SpecModel { var logger: KSPLogger? = null + private val stringTypeName = String::class.asTypeName() + private val vssNodeSetTypeName = Set::class.parameterizedBy(VssNode::class) + private val genericClassTypeName = KClass::class.asClassName().parameterizedBy(STAR).copy(nullable = true) + private val datatypeProperty: TypeName get() { return when (datatype) { @@ -246,8 +250,12 @@ internal class VssSpecificationSpecModel( // Add primitive data types if (specification.className == className) { members.forEach { member -> - val primitiveDataTypeSpec = createInterfaceDataTypeSpec(member) - propertySpecs.add(primitiveDataTypeSpec) + when (member.returnType.asTypeName()) { + stringTypeName -> createInterfaceDataTypeSpec(member) + else -> null + }?.let { primitiveDataTypeSpec -> + propertySpecs.add(primitiveDataTypeSpec) + } } return propertySpecs @@ -290,19 +298,16 @@ internal class VssSpecificationSpecModel( val propertySpecs = mutableListOf() - val members = VssSpecification::class.declaredMemberProperties - val setTypeName = Set::class.parameterizedBy(VssSpecification::class) - val classTypeName = KClass::class.asClassName().parameterizedBy(STAR).copy(nullable = true) + val members = VssNode::class.declaredMemberProperties members.forEach { member -> val memberName = member.name - - val propertySpec: PropertySpec? = when (val memberType = member.returnType.asTypeName()) { - setTypeName -> createSetSpec(memberName, memberType) - classTypeName -> createParentSpec(memberName, memberType) + when (val memberType = member.returnType.asTypeName()) { + vssNodeSetTypeName -> createSetSpec(memberName, memberType) + genericClassTypeName -> createParentSpec(memberName, memberType) else -> null + }?.let { propertySpec -> + propertySpecs.add(propertySpec) } - - propertySpec?.let { propertySpecs.add(it) } } return propertySpecs From 6d55337a3e2ccdee361c0e786be9da49fc3f5f4e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mark=20Hu=CC=88sers?= Date: Thu, 29 Feb 2024 17:16:39 +0100 Subject: [PATCH 05/20] chore: Rename VssSpecification -> VssNode --- .../databroker/JavaDataBrokerEngine.java | 6 ++-- .../kuksa/testapp/KuksaDataBrokerActivity.kt | 23 +++++++------ .../testapp/databroker/DataBrokerEngine.kt | 6 ++-- .../databroker/KotlinDataBrokerEngine.kt | 6 ++-- .../testapp/databroker/view/DataBrokerView.kt | 11 +++---- ...ificationsViewModel.kt => VssViewModel.kt} | 2 +- .../eclipse/kuksa/DataBrokerConnectionTest.kt | 6 ++-- ...Listener.kt => FriendlyVssNodeListener.kt} | 8 ++--- .../subscription/DataBrokerSubscriberTest.kt | 16 +++++----- .../VssDriver.kt | 2 +- .../VssNodeArithmeticTest.kt} | 6 ++-- .../VssNodeCopyTest.kt} | 26 +++++++-------- .../VssVehicle.kt | 2 +- ...VssSpecificationTest.kt => VssNodeTest.kt} | 4 +-- ...essor.kt => VssModelGeneratorProcessor.kt} | 2 +- .../{VssDefinitionParser.kt => VssParser.kt} | 6 ++-- ...mlDefinitionParser.kt => YamlVssParser.kt} | 18 +++++------ ...cationSpecModel.kt => VssNodeSpecModel.kt} | 0 .../parser/YamlDefinitionParserTest.kt | 8 ++--- ...ecModelTest.kt => VssNodeSpecModelTest.kt} | 32 +++++++++---------- 20 files changed, 94 insertions(+), 96 deletions(-) rename app/src/main/kotlin/org/eclipse/kuksa/testapp/databroker/viewmodel/{VssSpecificationsViewModel.kt => VssViewModel.kt} (97%) rename kuksa-sdk/src/test/kotlin/org/eclipse/kuksa/mocking/{FriendlyVssSpecificationListener.kt => FriendlyVssNodeListener.kt} (80%) rename kuksa-sdk/src/test/kotlin/org/eclipse/kuksa/{vssSpecification => vssNode}/VssDriver.kt (99%) rename kuksa-sdk/src/test/kotlin/org/eclipse/kuksa/{vssSpecification/VssSpecificationArithmeticTest.kt => vssNode/VssNodeArithmeticTest.kt} (95%) rename kuksa-sdk/src/test/kotlin/org/eclipse/kuksa/{vssSpecification/VssSpecificationCopyTest.kt => vssNode/VssNodeCopyTest.kt} (80%) rename kuksa-sdk/src/test/kotlin/org/eclipse/kuksa/{vssSpecification => vssNode}/VssVehicle.kt (98%) rename vss-core/src/test/java/org/eclipse/kuksa/vsscore/model/{VssSpecificationTest.kt => VssNodeTest.kt} (97%) rename vss-processor/src/main/kotlin/org/eclipse/kuksa/vssprocessor/{VssDefinitionProcessor.kt => VssModelGeneratorProcessor.kt} (98%) rename vss-processor/src/main/kotlin/org/eclipse/kuksa/vssprocessor/parser/{VssDefinitionParser.kt => VssParser.kt} (85%) rename vss-processor/src/main/kotlin/org/eclipse/kuksa/vssprocessor/parser/{YamlDefinitionParser.kt => YamlVssParser.kt} (88%) rename vss-processor/src/main/kotlin/org/eclipse/kuksa/vssprocessor/spec/{VssSpecificationSpecModel.kt => VssNodeSpecModel.kt} (100%) rename vss-processor/src/test/kotlin/org/eclipse/kuksa/vssprocessor/spec/{VssSpecificationSpecModelTest.kt => VssNodeSpecModelTest.kt} (81%) diff --git a/app/src/main/java/org/eclipse/kuksa/testapp/databroker/JavaDataBrokerEngine.java b/app/src/main/java/org/eclipse/kuksa/testapp/databroker/JavaDataBrokerEngine.java index e186c7d0..bef8af98 100644 --- a/app/src/main/java/org/eclipse/kuksa/testapp/databroker/JavaDataBrokerEngine.java +++ b/app/src/main/java/org/eclipse/kuksa/testapp/databroker/JavaDataBrokerEngine.java @@ -28,7 +28,7 @@ import org.eclipse.kuksa.DataBrokerConnector; import org.eclipse.kuksa.DisconnectListener; import org.eclipse.kuksa.PropertyListener; -import org.eclipse.kuksa.VssSpecificationListener; +import org.eclipse.kuksa.VssNodeListener; import org.eclipse.kuksa.model.Property; import org.eclipse.kuksa.proto.v1.KuksaValV1.GetResponse; import org.eclipse.kuksa.proto.v1.KuksaValV1.SetResponse; @@ -136,7 +136,7 @@ public void subscribe(@NonNull Property property, @NonNull PropertyListener prop @Override public void subscribe( @NonNull T specification, - @NonNull VssSpecificationListener specificationListener + @NonNull VssNodeListener specificationListener ) { if (dataBrokerConnection == null) { return; @@ -154,7 +154,7 @@ public void subscribe( @Override public void unsubscribe( @NonNull T specification, - @NonNull VssSpecificationListener specificationListener + @NonNull VssNodeListener specificationListener ) { if (dataBrokerConnection == null) { return; diff --git a/app/src/main/kotlin/org/eclipse/kuksa/testapp/KuksaDataBrokerActivity.kt b/app/src/main/kotlin/org/eclipse/kuksa/testapp/KuksaDataBrokerActivity.kt index ba049e4a..a1ca5f74 100644 --- a/app/src/main/kotlin/org/eclipse/kuksa/testapp/KuksaDataBrokerActivity.kt +++ b/app/src/main/kotlin/org/eclipse/kuksa/testapp/KuksaDataBrokerActivity.kt @@ -33,13 +33,12 @@ import org.eclipse.kuksa.CoroutineCallback import org.eclipse.kuksa.DataBrokerConnection import org.eclipse.kuksa.DisconnectListener import org.eclipse.kuksa.PropertyListener -import org.eclipse.kuksa.VssSpecificationListener +import org.eclipse.kuksa.VssNodeListener import org.eclipse.kuksa.extension.entriesMetadata import org.eclipse.kuksa.extension.valueType import org.eclipse.kuksa.model.Property import org.eclipse.kuksa.proto.v1.KuksaValV1 import org.eclipse.kuksa.proto.v1.KuksaValV1.GetResponse -import org.eclipse.kuksa.proto.v1.Types import org.eclipse.kuksa.proto.v1.Types.Datapoint import org.eclipse.kuksa.proto.v1.Types.Field import org.eclipse.kuksa.testapp.databroker.DataBrokerEngine @@ -53,7 +52,7 @@ import org.eclipse.kuksa.testapp.databroker.viewmodel.OutputEntry import org.eclipse.kuksa.testapp.databroker.viewmodel.OutputViewModel import org.eclipse.kuksa.testapp.databroker.viewmodel.TopAppBarViewModel import org.eclipse.kuksa.testapp.databroker.viewmodel.VSSPropertiesViewModel -import org.eclipse.kuksa.testapp.databroker.viewmodel.VssSpecificationsViewModel +import org.eclipse.kuksa.testapp.databroker.viewmodel.VssViewModel import org.eclipse.kuksa.testapp.extension.TAG import org.eclipse.kuksa.testapp.preferences.ConnectionInfoRepository import org.eclipse.kuksa.testapp.ui.theme.KuksaAppAndroidTheme @@ -69,7 +68,7 @@ class KuksaDataBrokerActivity : ComponentActivity() { ConnectionViewModel.Factory(connectionInfoRepository) } private val vssPropertiesViewModel: VSSPropertiesViewModel by viewModels() - private val vssSpecificationsViewModel: VssSpecificationsViewModel by viewModels() + private val vssViewModel: VssViewModel by viewModels() private val outputViewModel: OutputViewModel by viewModels() private val dataBrokerConnectionCallback = object : CoroutineCallback() { @@ -109,9 +108,9 @@ class KuksaDataBrokerActivity : ComponentActivity() { } } - private val specificationListener = object : VssSpecificationListener { - override fun onSpecificationChanged(vssSpecification: VssNode) { - outputViewModel.addOutputEntry("Updated specification: $vssSpecification") + private val specificationListener = object : VssNodeListener { + override fun onNodeChanged(vssNode: VssNode) { + outputViewModel.addOutputEntry("Updated specification: $vssNode") } override fun onError(throwable: Throwable) { @@ -141,7 +140,7 @@ class KuksaDataBrokerActivity : ComponentActivity() { topAppBarViewModel, connectionViewModel, vssPropertiesViewModel, - vssSpecificationsViewModel, + vssViewModel, outputViewModel, ) } @@ -187,15 +186,15 @@ class KuksaDataBrokerActivity : ComponentActivity() { dataBrokerEngine.unsubscribe(property, propertyListener) } - vssSpecificationsViewModel.onSubscribeSpecification = { specification -> + vssViewModel.onSubscribeSpecification = { specification -> dataBrokerEngine.subscribe(specification, specificationListener) } - vssSpecificationsViewModel.onUnsubscribeSpecification = { specification -> + vssViewModel.onUnsubscribeSpecification = { specification -> dataBrokerEngine.unsubscribe(specification, specificationListener) } - vssSpecificationsViewModel.onGetSpecification = { specification -> + vssViewModel.onGetSpecification = { specification -> fetchSpecification(specification) } } @@ -233,7 +232,7 @@ class KuksaDataBrokerActivity : ComponentActivity() { val automaticValueType = if (entriesMetadata.size == 1) { entriesMetadata.first().valueType } else { - Types.Datapoint.ValueCase.VALUE_NOT_SET + Datapoint.ValueCase.VALUE_NOT_SET } Log.d(TAG, "Fetched automatic value type from meta data: $automaticValueType") diff --git a/app/src/main/kotlin/org/eclipse/kuksa/testapp/databroker/DataBrokerEngine.kt b/app/src/main/kotlin/org/eclipse/kuksa/testapp/databroker/DataBrokerEngine.kt index 1648e333..e4852237 100644 --- a/app/src/main/kotlin/org/eclipse/kuksa/testapp/databroker/DataBrokerEngine.kt +++ b/app/src/main/kotlin/org/eclipse/kuksa/testapp/databroker/DataBrokerEngine.kt @@ -24,7 +24,7 @@ import org.eclipse.kuksa.CoroutineCallback import org.eclipse.kuksa.DataBrokerConnection import org.eclipse.kuksa.DisconnectListener import org.eclipse.kuksa.PropertyListener -import org.eclipse.kuksa.VssSpecificationListener +import org.eclipse.kuksa.VssNodeListener import org.eclipse.kuksa.model.Property import org.eclipse.kuksa.proto.v1.KuksaValV1.GetResponse import org.eclipse.kuksa.proto.v1.KuksaValV1.SetResponse @@ -61,12 +61,12 @@ interface DataBrokerEngine { fun subscribe( specification: T, - specificationListener: VssSpecificationListener, + specificationListener: VssNodeListener, ) fun unsubscribe( specification: T, - specificationListener: VssSpecificationListener, + specificationListener: VssNodeListener, ) fun disconnect() diff --git a/app/src/main/kotlin/org/eclipse/kuksa/testapp/databroker/KotlinDataBrokerEngine.kt b/app/src/main/kotlin/org/eclipse/kuksa/testapp/databroker/KotlinDataBrokerEngine.kt index 6d07fa6d..cd8860f8 100644 --- a/app/src/main/kotlin/org/eclipse/kuksa/testapp/databroker/KotlinDataBrokerEngine.kt +++ b/app/src/main/kotlin/org/eclipse/kuksa/testapp/databroker/KotlinDataBrokerEngine.kt @@ -28,7 +28,7 @@ import org.eclipse.kuksa.DataBrokerConnector import org.eclipse.kuksa.DataBrokerException import org.eclipse.kuksa.DisconnectListener import org.eclipse.kuksa.PropertyListener -import org.eclipse.kuksa.VssSpecificationListener +import org.eclipse.kuksa.VssNodeListener import org.eclipse.kuksa.model.Property import org.eclipse.kuksa.proto.v1.KuksaValV1.GetResponse import org.eclipse.kuksa.proto.v1.KuksaValV1.SetResponse @@ -117,7 +117,7 @@ class KotlinDataBrokerEngine( override fun subscribe( specification: T, - specificationListener: VssSpecificationListener, + specificationListener: VssNodeListener, ) { lifecycleScope.launch { dataBrokerConnection?.subscribe(specification, listener = specificationListener) @@ -126,7 +126,7 @@ class KotlinDataBrokerEngine( override fun unsubscribe( specification: T, - specificationListener: VssSpecificationListener, + specificationListener: VssNodeListener, ) { dataBrokerConnection?.unsubscribe(specification, listener = specificationListener) } diff --git a/app/src/main/kotlin/org/eclipse/kuksa/testapp/databroker/view/DataBrokerView.kt b/app/src/main/kotlin/org/eclipse/kuksa/testapp/databroker/view/DataBrokerView.kt index e6e475a8..fc9060f5 100644 --- a/app/src/main/kotlin/org/eclipse/kuksa/testapp/databroker/view/DataBrokerView.kt +++ b/app/src/main/kotlin/org/eclipse/kuksa/testapp/databroker/view/DataBrokerView.kt @@ -84,7 +84,7 @@ import org.eclipse.kuksa.testapp.databroker.viewmodel.OutputViewModel import org.eclipse.kuksa.testapp.databroker.viewmodel.TopAppBarViewModel import org.eclipse.kuksa.testapp.databroker.viewmodel.TopAppBarViewModel.DataBrokerMode import org.eclipse.kuksa.testapp.databroker.viewmodel.VSSPropertiesViewModel -import org.eclipse.kuksa.testapp.databroker.viewmodel.VssSpecificationsViewModel +import org.eclipse.kuksa.testapp.databroker.viewmodel.VssViewModel import org.eclipse.kuksa.testapp.extension.compose.Headline import org.eclipse.kuksa.testapp.extension.compose.OverflowMenu import org.eclipse.kuksa.testapp.extension.compose.SimpleExposedDropdownMenuBox @@ -99,13 +99,12 @@ val DefaultEdgePadding = 25.dp val DefaultElementPadding = 10.dp val MinimumButtonWidth = 150.dp -@OptIn(ExperimentalLayoutApi::class) @Composable fun DataBrokerView( topAppBarViewModel: TopAppBarViewModel, connectionViewModel: ConnectionViewModel, vssPropertiesViewModel: VSSPropertiesViewModel, - vssSpecificationsViewModel: VssSpecificationsViewModel, + vssViewModel: VssViewModel, outputViewModel: OutputViewModel, ) { Scaffold( @@ -128,7 +127,7 @@ fun DataBrokerView( if (connectionViewModel.isConnected) { when (dataBrokerMode) { DataBrokerMode.VSS_PATH -> DataBrokerProperties(vssPropertiesViewModel) - DataBrokerMode.SPECIFICATION -> DataBrokerSpecifications(vssSpecificationsViewModel) + DataBrokerMode.SPECIFICATION -> DataBrokerSpecifications(vssViewModel) } } Spacer(modifier = Modifier.padding(top = DefaultElementPadding)) @@ -235,7 +234,7 @@ private fun ConnectionStatusIcon( } @Composable -fun DataBrokerSpecifications(viewModel: VssSpecificationsViewModel) { +fun DataBrokerSpecifications(viewModel: VssViewModel) { Column { Headline(name = "Specifications") @@ -501,7 +500,7 @@ fun Preview() { TopAppBarViewModel(), ConnectionViewModel(connectionInfoRepository), VSSPropertiesViewModel(), - VssSpecificationsViewModel(), + VssViewModel(), OutputViewModel(), ) } diff --git a/app/src/main/kotlin/org/eclipse/kuksa/testapp/databroker/viewmodel/VssSpecificationsViewModel.kt b/app/src/main/kotlin/org/eclipse/kuksa/testapp/databroker/viewmodel/VssViewModel.kt similarity index 97% rename from app/src/main/kotlin/org/eclipse/kuksa/testapp/databroker/viewmodel/VssSpecificationsViewModel.kt rename to app/src/main/kotlin/org/eclipse/kuksa/testapp/databroker/viewmodel/VssViewModel.kt index 71c0e90e..d96d7202 100644 --- a/app/src/main/kotlin/org/eclipse/kuksa/testapp/databroker/viewmodel/VssSpecificationsViewModel.kt +++ b/app/src/main/kotlin/org/eclipse/kuksa/testapp/databroker/viewmodel/VssViewModel.kt @@ -29,7 +29,7 @@ import org.eclipse.kuksa.vss.VssVehicle import org.eclipse.kuksa.vsscore.model.VssNode import org.eclipse.kuksa.vsscore.model.heritage -class VssSpecificationsViewModel : ViewModel() { +class VssViewModel : ViewModel() { var onGetSpecification: (specification: VssNode) -> Unit = { } var onSubscribeSpecification: (specification: VssNode) -> Unit = { } var onUnsubscribeSpecification: (specification: VssNode) -> Unit = { } diff --git a/kuksa-sdk/src/test/kotlin/org/eclipse/kuksa/DataBrokerConnectionTest.kt b/kuksa-sdk/src/test/kotlin/org/eclipse/kuksa/DataBrokerConnectionTest.kt index e26af91c..c89c1fa9 100644 --- a/kuksa-sdk/src/test/kotlin/org/eclipse/kuksa/DataBrokerConnectionTest.kt +++ b/kuksa-sdk/src/test/kotlin/org/eclipse/kuksa/DataBrokerConnectionTest.kt @@ -32,14 +32,14 @@ import io.mockk.slot import io.mockk.verify import kotlinx.coroutines.runBlocking import org.eclipse.kuksa.databroker.DataBrokerConnectorProvider -import org.eclipse.kuksa.mocking.FriendlyVssSpecificationListener +import org.eclipse.kuksa.mocking.FriendlyVssNodeListener import org.eclipse.kuksa.model.Property import org.eclipse.kuksa.proto.v1.KuksaValV1 import org.eclipse.kuksa.proto.v1.Types import org.eclipse.kuksa.proto.v1.Types.Datapoint import org.eclipse.kuksa.test.kotest.DefaultDatabroker import org.eclipse.kuksa.test.kotest.Integration -import org.eclipse.kuksa.vssSpecification.VssDriver +import org.eclipse.kuksa.vssNode.VssDriver import org.junit.jupiter.api.Assertions.assertEquals import org.junit.jupiter.api.Assertions.assertFalse import org.junit.jupiter.api.Assertions.assertTrue @@ -165,7 +165,7 @@ class DataBrokerConnectionTest : BehaviorSpec({ } `when`("Subscribing to the specification") { - val specificationListener = FriendlyVssSpecificationListener() + val specificationListener = FriendlyVssNodeListener() dataBrokerConnection.subscribe(specification, listener = specificationListener) then("The #onSpecificationChanged method is triggered") { diff --git a/kuksa-sdk/src/test/kotlin/org/eclipse/kuksa/mocking/FriendlyVssSpecificationListener.kt b/kuksa-sdk/src/test/kotlin/org/eclipse/kuksa/mocking/FriendlyVssNodeListener.kt similarity index 80% rename from kuksa-sdk/src/test/kotlin/org/eclipse/kuksa/mocking/FriendlyVssSpecificationListener.kt rename to kuksa-sdk/src/test/kotlin/org/eclipse/kuksa/mocking/FriendlyVssNodeListener.kt index 1f2009b2..f1a4fe52 100644 --- a/kuksa-sdk/src/test/kotlin/org/eclipse/kuksa/mocking/FriendlyVssSpecificationListener.kt +++ b/kuksa-sdk/src/test/kotlin/org/eclipse/kuksa/mocking/FriendlyVssNodeListener.kt @@ -19,14 +19,14 @@ package org.eclipse.kuksa.mocking -import org.eclipse.kuksa.VssSpecificationListener +import org.eclipse.kuksa.VssNodeListener import org.eclipse.kuksa.vsscore.model.VssNode -class FriendlyVssSpecificationListener : VssSpecificationListener { +class FriendlyVssNodeListener : VssNodeListener { val updatedSpecifications = mutableListOf() val errors = mutableListOf() - override fun onSpecificationChanged(vssSpecification: T) { - updatedSpecifications.add(vssSpecification) + override fun onNodeChanged(vssNode: T) { + updatedSpecifications.add(vssNode) } override fun onError(throwable: Throwable) { diff --git a/kuksa-sdk/src/test/kotlin/org/eclipse/kuksa/subscription/DataBrokerSubscriberTest.kt b/kuksa-sdk/src/test/kotlin/org/eclipse/kuksa/subscription/DataBrokerSubscriberTest.kt index 52f2c58b..7dad622e 100644 --- a/kuksa-sdk/src/test/kotlin/org/eclipse/kuksa/subscription/DataBrokerSubscriberTest.kt +++ b/kuksa-sdk/src/test/kotlin/org/eclipse/kuksa/subscription/DataBrokerSubscriberTest.kt @@ -35,14 +35,14 @@ import org.eclipse.kuksa.extensions.toggleBoolean import org.eclipse.kuksa.extensions.updateRandomFloatValue import org.eclipse.kuksa.extensions.updateRandomUint32Value import org.eclipse.kuksa.mocking.FriendlyPropertyListener -import org.eclipse.kuksa.mocking.FriendlyVssSpecificationListener +import org.eclipse.kuksa.mocking.FriendlyVssNodeListener import org.eclipse.kuksa.pattern.listener.MultiListener import org.eclipse.kuksa.pattern.listener.count import org.eclipse.kuksa.proto.v1.Types import org.eclipse.kuksa.test.kotest.DefaultDatabroker import org.eclipse.kuksa.test.kotest.Insecure import org.eclipse.kuksa.test.kotest.Integration -import org.eclipse.kuksa.vssSpecification.VssDriver +import org.eclipse.kuksa.vssNode.VssDriver import kotlin.time.Duration.Companion.milliseconds import kotlin.time.Duration.Companion.seconds @@ -230,12 +230,12 @@ class DataBrokerSubscriberTest : BehaviorSpec({ val specification = VssDriver.VssHeartRate() - `when`("Subscribing using VssSpecification to Vehicle.Driver.HeartRate with Field FIELD_VALUE") { - val friendlyVssSpecificationListener = FriendlyVssSpecificationListener() + `when`("Subscribing using a VSS node to Vehicle.Driver.HeartRate with Field FIELD_VALUE") { + val friendlyVssNodeListener = FriendlyVssNodeListener() classUnderTest.subscribe( specification, Types.Field.FIELD_VALUE, - friendlyVssSpecificationListener, + friendlyVssNodeListener, ) and("The value of Vehicle.Driver.HeartRate changes") { @@ -244,10 +244,10 @@ class DataBrokerSubscriberTest : BehaviorSpec({ then("The Observer should be triggered") { eventually(1.seconds) { - friendlyVssSpecificationListener.updatedSpecifications.size shouldBe 2 + friendlyVssNodeListener.updatedSpecifications.size shouldBe 2 } - val count = friendlyVssSpecificationListener.updatedSpecifications + val count = friendlyVssNodeListener.updatedSpecifications .count { it.value == randomIntValue } count shouldBe 1 } @@ -255,7 +255,7 @@ class DataBrokerSubscriberTest : BehaviorSpec({ } `when`("Subscribing the same SpecificationObserver twice to Vehicle.Driver.HeartRate") { - val specificationObserverMock = FriendlyVssSpecificationListener() + val specificationObserverMock = FriendlyVssNodeListener() classUnderTest.subscribe( specification, Types.Field.FIELD_VALUE, diff --git a/kuksa-sdk/src/test/kotlin/org/eclipse/kuksa/vssSpecification/VssDriver.kt b/kuksa-sdk/src/test/kotlin/org/eclipse/kuksa/vssNode/VssDriver.kt similarity index 99% rename from kuksa-sdk/src/test/kotlin/org/eclipse/kuksa/vssSpecification/VssDriver.kt rename to kuksa-sdk/src/test/kotlin/org/eclipse/kuksa/vssNode/VssDriver.kt index 83c3102a..995ab6dd 100644 --- a/kuksa-sdk/src/test/kotlin/org/eclipse/kuksa/vssSpecification/VssDriver.kt +++ b/kuksa-sdk/src/test/kotlin/org/eclipse/kuksa/vssNode/VssDriver.kt @@ -17,7 +17,7 @@ * */ -package org.eclipse.kuksa.vssSpecification +package org.eclipse.kuksa.vssNode import org.eclipse.kuksa.vsscore.model.VssLeaf import org.eclipse.kuksa.vsscore.model.VssNode diff --git a/kuksa-sdk/src/test/kotlin/org/eclipse/kuksa/vssSpecification/VssSpecificationArithmeticTest.kt b/kuksa-sdk/src/test/kotlin/org/eclipse/kuksa/vssNode/VssNodeArithmeticTest.kt similarity index 95% rename from kuksa-sdk/src/test/kotlin/org/eclipse/kuksa/vssSpecification/VssSpecificationArithmeticTest.kt rename to kuksa-sdk/src/test/kotlin/org/eclipse/kuksa/vssNode/VssNodeArithmeticTest.kt index 22de38a2..6bb8d052 100644 --- a/kuksa-sdk/src/test/kotlin/org/eclipse/kuksa/vssSpecification/VssSpecificationArithmeticTest.kt +++ b/kuksa-sdk/src/test/kotlin/org/eclipse/kuksa/vssNode/VssNodeArithmeticTest.kt @@ -16,7 +16,7 @@ * SPDX-License-Identifier: Apache-2.0 */ -package org.eclipse.kuksa.vssSpecification +package org.eclipse.kuksa.vssNode import io.kotest.assertions.throwables.shouldThrow import io.kotest.core.spec.style.BehaviorSpec @@ -28,10 +28,10 @@ import org.eclipse.kuksa.extension.vssProperty.plus import org.eclipse.kuksa.extension.vssProperty.times import org.eclipse.kuksa.test.kotest.Unit -class VssSpecificationArithmeticTest : BehaviorSpec({ +class VssNodeArithmeticTest : BehaviorSpec({ tags(Unit) - given("VssSpecification values for arithmetic operations") { + given("VssNode values for arithmetic operations") { val valueInt = VssValueInt(value = 100) val valueFloat = VssValueFloat(value = 100f) val valueLong = VssValueLong(value = 100L) diff --git a/kuksa-sdk/src/test/kotlin/org/eclipse/kuksa/vssSpecification/VssSpecificationCopyTest.kt b/kuksa-sdk/src/test/kotlin/org/eclipse/kuksa/vssNode/VssNodeCopyTest.kt similarity index 80% rename from kuksa-sdk/src/test/kotlin/org/eclipse/kuksa/vssSpecification/VssSpecificationCopyTest.kt rename to kuksa-sdk/src/test/kotlin/org/eclipse/kuksa/vssNode/VssNodeCopyTest.kt index a9102ce2..b47a096b 100644 --- a/kuksa-sdk/src/test/kotlin/org/eclipse/kuksa/vssSpecification/VssSpecificationCopyTest.kt +++ b/kuksa-sdk/src/test/kotlin/org/eclipse/kuksa/vssNode/VssNodeCopyTest.kt @@ -17,7 +17,7 @@ * */ -package org.eclipse.kuksa.vssSpecification +package org.eclipse.kuksa.vssNode import io.kotest.assertions.throwables.shouldThrow import io.kotest.core.spec.style.BehaviorSpec @@ -32,7 +32,7 @@ import org.eclipse.kuksa.proto.v1.Types import org.eclipse.kuksa.test.kotest.Unit import org.eclipse.kuksa.vsscore.model.VssLeaf -class VssSpecificationCopyTest : BehaviorSpec({ +class VssNodeCopyTest : BehaviorSpec({ tags(Unit) given("A specification") { @@ -44,10 +44,10 @@ class VssSpecificationCopyTest : BehaviorSpec({ val updatedHeartRate = VssDriver.VssHeartRate(value = newValue) `when`("a deep copy is done with a changed heritage line") { - val deepCopiedSpecification = vehicle.deepCopy(0, updatedHeartRate) + val deepCopiedNode = vehicle.deepCopy(0, updatedHeartRate) then("it should return the new children as a copy") { - val heartRate = deepCopiedSpecification.driver.heartRate + val heartRate = deepCopiedNode.driver.heartRate heartRate shouldBeSameInstanceAs updatedHeartRate } @@ -55,10 +55,10 @@ class VssSpecificationCopyTest : BehaviorSpec({ } `when`("a value copy is done via the not operator") { - val invertedSpecification = !vehicle.driver.isEyesOnRoad + val invertedNode = !vehicle.driver.isEyesOnRoad then("it should return a copy with the inverted value") { - invertedSpecification.value shouldBe true + invertedNode.value shouldBe true } } @@ -67,10 +67,10 @@ class VssSpecificationCopyTest : BehaviorSpec({ `when`("a deep copy is done via the invoke operator") { val copiedHeartRate = driverHeartRate(newValue) - val copiedSpecification = vehicle(copiedHeartRate) + val copiedNode = vehicle(copiedHeartRate) then("it should return a copy with the updated value") { - val heartRate = copiedSpecification.driver.heartRate + val heartRate = copiedNode.driver.heartRate heartRate shouldBeSameInstanceAs copiedHeartRate } @@ -82,10 +82,10 @@ class VssSpecificationCopyTest : BehaviorSpec({ val datapoint = Types.Datapoint.newBuilder().setInt32(newValue).build() `when`("a copy is done") { - val copiedSpecification = driverHeartRate.copy(datapoint) + val copiedNode = driverHeartRate.copy(datapoint) then("it should return a copy with the updated value") { - val heartRateValue = copiedSpecification.value + val heartRateValue = copiedNode.value heartRateValue shouldBe newValue } @@ -95,10 +95,10 @@ class VssSpecificationCopyTest : BehaviorSpec({ val vssPath = driverHeartRate.vssPath `when`("a copy is done") { - val copiedSpecification = driverHeartRate.copy(vssPath, datapoint) + val copiedNode = driverHeartRate.copy(vssPath, datapoint) then("it should return a copy with the updated value") { - val heartRateValue = copiedSpecification.value + val heartRateValue = copiedNode.value heartRateValue shouldBe newValue } @@ -109,7 +109,7 @@ class VssSpecificationCopyTest : BehaviorSpec({ and("an empty DataPoint") { val datapoint = Types.Datapoint.newBuilder().build() - and("an invalid VssSpecification") { + and("an invalid VssLeaf") { val invalidSpecification = VssInvalid() `when`("a copy is done") { diff --git a/kuksa-sdk/src/test/kotlin/org/eclipse/kuksa/vssSpecification/VssVehicle.kt b/kuksa-sdk/src/test/kotlin/org/eclipse/kuksa/vssNode/VssVehicle.kt similarity index 98% rename from kuksa-sdk/src/test/kotlin/org/eclipse/kuksa/vssSpecification/VssVehicle.kt rename to kuksa-sdk/src/test/kotlin/org/eclipse/kuksa/vssNode/VssVehicle.kt index 1dbd3172..ee8fb11a 100644 --- a/kuksa-sdk/src/test/kotlin/org/eclipse/kuksa/vssSpecification/VssVehicle.kt +++ b/kuksa-sdk/src/test/kotlin/org/eclipse/kuksa/vssNode/VssVehicle.kt @@ -17,7 +17,7 @@ * */ -package org.eclipse.kuksa.vssSpecification +package org.eclipse.kuksa.vssNode import org.eclipse.kuksa.vsscore.model.VssLeaf import org.eclipse.kuksa.vsscore.model.VssNode diff --git a/vss-core/src/test/java/org/eclipse/kuksa/vsscore/model/VssSpecificationTest.kt b/vss-core/src/test/java/org/eclipse/kuksa/vsscore/model/VssNodeTest.kt similarity index 97% rename from vss-core/src/test/java/org/eclipse/kuksa/vsscore/model/VssSpecificationTest.kt rename to vss-core/src/test/java/org/eclipse/kuksa/vsscore/model/VssNodeTest.kt index 6611a4af..d064c547 100644 --- a/vss-core/src/test/java/org/eclipse/kuksa/vsscore/model/VssSpecificationTest.kt +++ b/vss-core/src/test/java/org/eclipse/kuksa/vsscore/model/VssNodeTest.kt @@ -21,7 +21,7 @@ package org.eclipse.kuksa.vsscore.model import io.kotest.core.spec.style.BehaviorSpec import io.kotest.matchers.shouldBe -class VssSpecificationTest : BehaviorSpec({ +class VssNodeTest : BehaviorSpec({ given("The root level specification") { val vssVehicle = VssVehicle() `when`("finding the whole heritage") { @@ -62,7 +62,7 @@ class VssSpecificationTest : BehaviorSpec({ } } - given("A child VssSpecification") { + given("A child VssNode") { val vssDriver = VssDriver() `when`("splitting it into path components") { val pathComponents = vssDriver.vssPathComponents diff --git a/vss-processor/src/main/kotlin/org/eclipse/kuksa/vssprocessor/VssDefinitionProcessor.kt b/vss-processor/src/main/kotlin/org/eclipse/kuksa/vssprocessor/VssModelGeneratorProcessor.kt similarity index 98% rename from vss-processor/src/main/kotlin/org/eclipse/kuksa/vssprocessor/VssDefinitionProcessor.kt rename to vss-processor/src/main/kotlin/org/eclipse/kuksa/vssprocessor/VssModelGeneratorProcessor.kt index 1d190b75..53d163d2 100644 --- a/vss-processor/src/main/kotlin/org/eclipse/kuksa/vssprocessor/VssDefinitionProcessor.kt +++ b/vss-processor/src/main/kotlin/org/eclipse/kuksa/vssprocessor/VssModelGeneratorProcessor.kt @@ -44,7 +44,7 @@ import org.eclipse.kuksa.vssprocessor.spec.VssSpecificationSpecModel import java.io.File /** - * Generates a [VssNode] for every specification listed in the input file. + * Generates a [org.eclipse.kuksa.vsscore.model.VssNode] for every specification listed in the input file. * These nodes are a usable kotlin data class reflection of the specification. * * @param codeGenerator to generate class files with diff --git a/vss-processor/src/main/kotlin/org/eclipse/kuksa/vssprocessor/parser/VssDefinitionParser.kt b/vss-processor/src/main/kotlin/org/eclipse/kuksa/vssprocessor/parser/VssParser.kt similarity index 85% rename from vss-processor/src/main/kotlin/org/eclipse/kuksa/vssprocessor/parser/VssDefinitionParser.kt rename to vss-processor/src/main/kotlin/org/eclipse/kuksa/vssprocessor/parser/VssParser.kt index 8448497b..4949d476 100644 --- a/vss-processor/src/main/kotlin/org/eclipse/kuksa/vssprocessor/parser/VssDefinitionParser.kt +++ b/vss-processor/src/main/kotlin/org/eclipse/kuksa/vssprocessor/parser/VssParser.kt @@ -19,16 +19,16 @@ package org.eclipse.kuksa.vssprocessor.parser -import org.eclipse.kuksa.vssprocessor.spec.VssSpecificationSpecModel +import org.eclipse.kuksa.vssprocessor.spec.VssNodeSpecModel import java.io.File internal interface VssDefinitionParser { /** - * @param definitionFile to parse [VssSpecificationSpecModel] with + * @param definitionFile to parse [VssNodeSpecModel] with * @param elementDelimiter which is the separator string between the specifications. The default is an empty line. */ fun parseSpecifications( definitionFile: File, elementDelimiter: String = "", - ): List + ): List } diff --git a/vss-processor/src/main/kotlin/org/eclipse/kuksa/vssprocessor/parser/YamlDefinitionParser.kt b/vss-processor/src/main/kotlin/org/eclipse/kuksa/vssprocessor/parser/YamlVssParser.kt similarity index 88% rename from vss-processor/src/main/kotlin/org/eclipse/kuksa/vssprocessor/parser/YamlDefinitionParser.kt rename to vss-processor/src/main/kotlin/org/eclipse/kuksa/vssprocessor/parser/YamlVssParser.kt index c4fd3778..4e6811b2 100644 --- a/vss-processor/src/main/kotlin/org/eclipse/kuksa/vssprocessor/parser/YamlDefinitionParser.kt +++ b/vss-processor/src/main/kotlin/org/eclipse/kuksa/vssprocessor/parser/YamlVssParser.kt @@ -20,15 +20,15 @@ package org.eclipse.kuksa.vssprocessor.parser import org.eclipse.kuksa.vsscore.model.VssNode -import org.eclipse.kuksa.vssprocessor.spec.VssSpecificationSpecModel +import org.eclipse.kuksa.vssprocessor.spec.VssNodeSpecModel import java.io.File import kotlin.reflect.KMutableProperty import kotlin.reflect.KProperty import kotlin.reflect.full.memberProperties internal class YamlDefinitionParser : VssDefinitionParser { - override fun parseSpecifications(definitionFile: File, elementDelimiter: String): List { - val specificationElements = mutableListOf() + override fun parseSpecifications(definitionFile: File, elementDelimiter: String): List { + val specificationElements = mutableListOf() definitionFile.useLines { lines -> val yamlAttributes = mutableListOf() for (line in lines.toList()) { @@ -61,14 +61,14 @@ internal class YamlDefinitionParser : VssDefinitionParser { // description: Antilock Braking System signals. // type: branch // uuid: 219270ef27c4531f874bbda63743b330 - private fun parseYamlElement(yamlElement: List, delimiter: Char = ';'): VssSpecificationSpecModel? { + private fun parseYamlElement(yamlElement: List, delimiter: Char = ';'): VssNodeSpecModel? { val elementVssPath = yamlElement.first().substringBefore(":") val yamlElementJoined = yamlElement .joinToString(separator = delimiter.toString()) .substringAfter(delimiter) // Remove vssPath (already parsed) .prependIndent(delimiter.toString()) // So the parsing is consistent for the first element - val members = VssSpecificationSpecModel::class.memberProperties + val members = VssNodeSpecModel::class.memberProperties val fieldsToSet = mutableListOf>() // The VSSPath is an exception because it is parsed from the top level name. @@ -89,12 +89,12 @@ internal class YamlDefinitionParser : VssDefinitionParser { fieldsToSet.add(fieldInfo) } - val vssSpecificationMember = VssSpecificationSpecModel() - vssSpecificationMember.setFields(fieldsToSet) + val vssNodeMember = VssNodeSpecModel() + vssNodeMember.setFields(fieldsToSet) - if (vssSpecificationMember.uuid.isEmpty()) return null + if (vssNodeMember.uuid.isEmpty()) return null - return vssSpecificationMember + return vssNodeMember } } diff --git a/vss-processor/src/main/kotlin/org/eclipse/kuksa/vssprocessor/spec/VssSpecificationSpecModel.kt b/vss-processor/src/main/kotlin/org/eclipse/kuksa/vssprocessor/spec/VssNodeSpecModel.kt similarity index 100% rename from vss-processor/src/main/kotlin/org/eclipse/kuksa/vssprocessor/spec/VssSpecificationSpecModel.kt rename to vss-processor/src/main/kotlin/org/eclipse/kuksa/vssprocessor/spec/VssNodeSpecModel.kt diff --git a/vss-processor/src/test/kotlin/org/eclipse/kuksa/vssprocessor/parser/YamlDefinitionParserTest.kt b/vss-processor/src/test/kotlin/org/eclipse/kuksa/vssprocessor/parser/YamlDefinitionParserTest.kt index 0d0b9a7c..d8bdd514 100644 --- a/vss-processor/src/test/kotlin/org/eclipse/kuksa/vssprocessor/parser/YamlDefinitionParserTest.kt +++ b/vss-processor/src/test/kotlin/org/eclipse/kuksa/vssprocessor/parser/YamlDefinitionParserTest.kt @@ -24,7 +24,7 @@ import java.io.File class YamlDefinitionParserTest : BehaviorSpec({ given("A parser for yaml files") { - val parser = YamlDefinitionParser() + val parser = YamlVssParser() val classLoader = parser::class.java.classLoader!! and("a specification file of version 4") { @@ -32,7 +32,7 @@ class YamlDefinitionParserTest : BehaviorSpec({ val specificationFile = File(resourceUrl.path) `when`("parsing the file") { - val parsedSpecifications = parser.parseSpecifications(specificationFile) + val parsedSpecifications = parser.parseNodes(specificationFile) then("the correct number of specification models should be parsed") { // These are exactly the specifications defined in the 4.0 file @@ -45,7 +45,7 @@ class YamlDefinitionParserTest : BehaviorSpec({ val incompatibleFile = File(incompatibleResourceUrl.path) `when`("parsing the file") { - val parsedSpecifications = parser.parseSpecifications(incompatibleFile) + val parsedSpecifications = parser.parseNodes(incompatibleFile) then("no entries should be returned") { parsedSpecifications.size shouldBe 0 @@ -57,7 +57,7 @@ class YamlDefinitionParserTest : BehaviorSpec({ val invalidFile = File(invalidResourceUrl.path) `when`("parsing the file") { - val parsedSpecifications = parser.parseSpecifications(invalidFile) + val parsedSpecifications = parser.parseNodes(invalidFile) then("no entries should be returned") { parsedSpecifications.size shouldBe 0 diff --git a/vss-processor/src/test/kotlin/org/eclipse/kuksa/vssprocessor/spec/VssSpecificationSpecModelTest.kt b/vss-processor/src/test/kotlin/org/eclipse/kuksa/vssprocessor/spec/VssNodeSpecModelTest.kt similarity index 81% rename from vss-processor/src/test/kotlin/org/eclipse/kuksa/vssprocessor/spec/VssSpecificationSpecModelTest.kt rename to vss-processor/src/test/kotlin/org/eclipse/kuksa/vssprocessor/spec/VssNodeSpecModelTest.kt index 9f70a262..b296003d 100644 --- a/vss-processor/src/test/kotlin/org/eclipse/kuksa/vssprocessor/spec/VssSpecificationSpecModelTest.kt +++ b/vss-processor/src/test/kotlin/org/eclipse/kuksa/vssprocessor/spec/VssNodeSpecModelTest.kt @@ -24,9 +24,9 @@ import io.kotest.matchers.shouldBe import io.kotest.matchers.shouldNotBe import io.kotest.matchers.string.shouldContain -class VssSpecificationSpecModelTest : BehaviorSpec({ +class VssNodeSpecModelTest : BehaviorSpec({ given("String spec model") { - val specModel = VssSpecificationSpecModel(datatype = "string", vssPath = "Vehicle.IgnitionType") + val specModel = VssNodeSpecModel(datatype = "string", vssPath = "Vehicle.IgnitionType") `when`("creating a class spec") { val classSpec = specModel.createClassSpec("test") @@ -40,7 +40,7 @@ class VssSpecificationSpecModelTest : BehaviorSpec({ } given("int64 spec model") { - val specModel = VssSpecificationSpecModel(datatype = "int64", vssPath = "Vehicle.IgnitionType") + val specModel = VssNodeSpecModel(datatype = "int64", vssPath = "Vehicle.IgnitionType") `when`("creating a class spec") { val classSpec = specModel.createClassSpec("test") @@ -54,7 +54,7 @@ class VssSpecificationSpecModelTest : BehaviorSpec({ } given("uint32 spec model") { - val specModel = VssSpecificationSpecModel(datatype = "uint32", vssPath = "Vehicle.IgnitionType") + val specModel = VssNodeSpecModel(datatype = "uint32", vssPath = "Vehicle.IgnitionType") `when`("creating a class spec") { val classSpec = specModel.createClassSpec("test") @@ -68,7 +68,7 @@ class VssSpecificationSpecModelTest : BehaviorSpec({ } given("int32 spec model") { - val specModel = VssSpecificationSpecModel(datatype = "int32", vssPath = "Vehicle.IgnitionType") + val specModel = VssNodeSpecModel(datatype = "int32", vssPath = "Vehicle.IgnitionType") `when`("creating a class spec") { val classSpec = specModel.createClassSpec("test") @@ -82,7 +82,7 @@ class VssSpecificationSpecModelTest : BehaviorSpec({ } given("uint64[] spec model") { - val specModel = VssSpecificationSpecModel(datatype = "uint64[]", vssPath = "Vehicle.IgnitionType") + val specModel = VssNodeSpecModel(datatype = "uint64[]", vssPath = "Vehicle.IgnitionType") `when`("creating a class spec") { val classSpec = specModel.createClassSpec("test") @@ -96,7 +96,7 @@ class VssSpecificationSpecModelTest : BehaviorSpec({ } given("String[] spec model") { - val specModel = VssSpecificationSpecModel(datatype = "string[]", vssPath = "Vehicle.IgnitionType") + val specModel = VssNodeSpecModel(datatype = "string[]", vssPath = "Vehicle.IgnitionType") `when`("creating a class spec") { val classSpec = specModel.createClassSpec("test") @@ -110,7 +110,7 @@ class VssSpecificationSpecModelTest : BehaviorSpec({ } given("Boolean[] spec model") { - val specModel = VssSpecificationSpecModel(datatype = "boolean[]", vssPath = "Vehicle.IgnitionType") + val specModel = VssNodeSpecModel(datatype = "boolean[]", vssPath = "Vehicle.IgnitionType") `when`("creating a class spec") { val classSpec = specModel.createClassSpec("test") @@ -124,7 +124,7 @@ class VssSpecificationSpecModelTest : BehaviorSpec({ } given("Any spec model") { - val specModel = VssSpecificationSpecModel(datatype = "any", vssPath = "Vehicle.IgnitionType") + val specModel = VssNodeSpecModel(datatype = "any", vssPath = "Vehicle.IgnitionType") `when`("creating a class spec") { val exception = shouldThrow { @@ -138,7 +138,7 @@ class VssSpecificationSpecModelTest : BehaviorSpec({ } given("Parent Spec model") { - val specModel = VssSpecificationSpecModel(vssPath = "Vehicle") + val specModel = VssNodeSpecModel(vssPath = "Vehicle") `when`("creating a class spec without children and nested classes") { val exception = shouldThrow { @@ -150,14 +150,14 @@ class VssSpecificationSpecModelTest : BehaviorSpec({ } } and("related specifications") { - val vehicleSpeedSpecModel = VssSpecificationSpecModel(datatype = "float", vssPath = "Vehicle.Speed") + val vehicleSpeedSpecModel = VssNodeSpecModel(datatype = "float", vssPath = "Vehicle.Speed") val relatedSpecifications = listOf( - VssSpecificationSpecModel(vssPath = "Vehicle.SmartphoneProjection"), - VssSpecificationSpecModel(datatype = "boolean", vssPath = "Vehicle.IsBrokenDown"), + VssNodeSpecModel(vssPath = "Vehicle.SmartphoneProjection"), + VssNodeSpecModel(datatype = "boolean", vssPath = "Vehicle.IsBrokenDown"), vehicleSpeedSpecModel, - VssSpecificationSpecModel(datatype = "string[]", vssPath = "Vehicle.SupportedMode"), - VssSpecificationSpecModel(datatype = "boolean[]", vssPath = "Vehicle.AreSeatsHeated"), - VssSpecificationSpecModel(datatype = "invalid", vssPath = "Vehicle.Invalid"), + VssNodeSpecModel(datatype = "string[]", vssPath = "Vehicle.SupportedMode"), + VssNodeSpecModel(datatype = "boolean[]", vssPath = "Vehicle.AreSeatsHeated"), + VssNodeSpecModel(datatype = "invalid", vssPath = "Vehicle.Invalid"), ) `when`("creating a class spec with children") { From ed2f24aa4ed99c36dbb33ac314bcab3cc27bd871 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mark=20Hu=CC=88sers?= Date: Thu, 29 Feb 2024 22:10:17 +0100 Subject: [PATCH 06/20] chore: Rename VssDefinition -> VssModelGenerator The Definition wording is kinda redundant with what VSS means (Specification). So the annotation name was changed to something it is actually responsible for: Triggering the generation of Models. --- .../kuksa/testapp/KuksaDataBrokerActivity.kt | 4 +- docs/QUICKSTART.md | 28 +++++------ docs/kuksa-sdk_class-diagram.puml | 12 ++--- docs/kuksa-vss-core_class-diagram.puml | 14 ++---- docs/kuksa-vss-processor_class-diagram.puml | 30 ++++++------ .../org/eclipse/kuksa/DataBrokerConnection.kt | 10 ++-- .../org/eclipse/kuksa/PropertyListener.kt | 8 ++-- .../VssSpecificationCopyExtension.kt | 6 +-- .../subscription/DataBrokerSubscriber.kt | 8 ++-- .../SpecificationPropertyListener.kt | 12 ++--- .../java/com/example/sample/JavaActivity.java | 10 ++-- .../com/example/sample/KotlinActivity.kt | 10 ++-- ...{VssDefinition.kt => VssModelGenerator.kt} | 8 ++-- .../vssprocessor/plugin/VssProcessorPlugin.kt | 18 +++---- .../plugin/VssProcessorPluginTest.kt | 47 ++++++++++--------- .../VssModelGeneratorProcessor.kt | 44 ++++++++--------- .../kuksa/vssprocessor/parser/VssParser.kt | 4 +- .../vssprocessor/parser/YamlVssParser.kt | 4 +- .../kuksa/vssprocessor/spec/SpecModel.kt | 4 +- .../vssprocessor/spec/VssNodeSpecModel.kt | 16 +++---- ...ols.ksp.processing.SymbolProcessorProvider | 2 +- 21 files changed, 144 insertions(+), 155 deletions(-) rename vss-core/src/main/java/org/eclipse/kuksa/vsscore/annotation/{VssDefinition.kt => VssModelGenerator.kt} (88%) diff --git a/app/src/main/kotlin/org/eclipse/kuksa/testapp/KuksaDataBrokerActivity.kt b/app/src/main/kotlin/org/eclipse/kuksa/testapp/KuksaDataBrokerActivity.kt index a1ca5f74..ff08c4c9 100644 --- a/app/src/main/kotlin/org/eclipse/kuksa/testapp/KuksaDataBrokerActivity.kt +++ b/app/src/main/kotlin/org/eclipse/kuksa/testapp/KuksaDataBrokerActivity.kt @@ -56,10 +56,10 @@ import org.eclipse.kuksa.testapp.databroker.viewmodel.VssViewModel import org.eclipse.kuksa.testapp.extension.TAG import org.eclipse.kuksa.testapp.preferences.ConnectionInfoRepository import org.eclipse.kuksa.testapp.ui.theme.KuksaAppAndroidTheme -import org.eclipse.kuksa.vsscore.annotation.VssDefinition +import org.eclipse.kuksa.vsscore.annotation.VssModelGenerator import org.eclipse.kuksa.vsscore.model.VssNode -@VssDefinition +@VssModelGenerator class KuksaDataBrokerActivity : ComponentActivity() { private lateinit var connectionInfoRepository: ConnectionInfoRepository diff --git a/docs/QUICKSTART.md b/docs/QUICKSTART.md index 9e7bea79..1fe67495 100644 --- a/docs/QUICKSTART.md +++ b/docs/QUICKSTART.md @@ -178,20 +178,14 @@ vssProcessor { } ``` -Use the new [`VssDefinition`](https://github.com/eclipse-kuksa/kuksa-android-sdk/blob/main/vss-core/src/main/java/org/eclipse/kuksa/vsscore/annotation/VssDefinition.kt) annotation and provide the path to the specification file (Inside the assets folder). +Use the [`VssModelGenerator`](https://github.com/eclipse-kuksa/kuksa-android-sdk/blob/main/vss-core/src/main/java/org/eclipse/kuksa/vsscore/annotation/VssModelGenerator.kt) annotation and provide the path to the specification file (Inside the assets folder). Doing so will generate a complete tree of Kotlin models which can be used in combination with the SDK API. This way you can work with safe types and the SDK takes care of all the model parsing for you. There is also a whole set of -convenience operators and extension methods to work with to manipulate the tree data. See the `VssSpecification` class documentation for this. +convenience operators and extension methods to work with to manipulate the tree data. See the `VssNode` class documentation for this. -*Kotlin* -```kotlin -@VssDefinition -class KotlinActivity -``` -*Java* -```java -@VssDefinition -public class JavaActivity +```kotlin / Java +@VssModelGenerator +class Activity ``` > [!IMPORTANT] > Keep in mind to always synchronize the specification file between the client and the Databroker. @@ -228,7 +222,7 @@ data class VssSpeed @JvmOverloads constructor( override val vssPath: String get() = "Vehicle.Speed" - override val children: Set + override val children: Set get() = setOf() override val parentClass: KClass<*> @@ -257,8 +251,8 @@ fun update() { fun subscribe() { val vssSpeed = VssVehicle.VssSpeed(value = 100f) - dataBrokerConnection?.subscribe(vssSpeed, listener = object : VssSpecificationListener { - override fun onSpecificationChanged(vssSpecification: VssVehicle.VssSpeed) { + dataBrokerConnection?.subscribe(vssSpeed, listener = object : VssNodeListener { + override fun onNodeChanged(vssNode: VssVehicle.VssSpeed) { val speed = vssSpeed.value } @@ -313,10 +307,10 @@ void subscribe() { dataBrokerConnection.subscribe( vssSpeed, Collections.singleton(Types.Field.FIELD_VALUE), - new VssSpecificationListener() { + new VssNodeListener() { @Override - public void onSpecificationChanged(@NonNull VssVehicle.VssSpeed vssSpecification) { - Float speed = vssSpecification.getValue(); + public void onSpecificationChanged(@NonNull VssVehicle.VssSpeed vssNode) { + Float speed = vssNode.getValue(); } @Override diff --git a/docs/kuksa-sdk_class-diagram.puml b/docs/kuksa-sdk_class-diagram.puml index 2d7eece8..2f48b935 100644 --- a/docs/kuksa-sdk_class-diagram.puml +++ b/docs/kuksa-sdk_class-diagram.puml @@ -54,9 +54,9 @@ package kuksa { class DataBrokerSubscriber { + subscribe(vssPath: String, Field, PropertyListener) - + subscribe(T, Field, VssSpecificationListener) + + subscribe(T, Field, VssNodeListener) + unsubscribe(vssPath: String, Field, PropertyListener) - + unsubscribe(T, Field, VssSpecificationListener) + + unsubscribe(T, Field, VssNodeListener) } class DataBrokerConnection { @@ -64,13 +64,13 @@ package kuksa { + jsonWebToken: JsonWebToken + subscribe(Property, PropertyListener) - + subscribe(T, Collection, VssSpecificationListener) + + subscribe(T, Collection, VssNodeListener) + unsubscribe(Property, PropertyListener) - + unsubscribe(T, Collection, VssSpecificationListener) + + unsubscribe(T, Collection, VssNodeListener) + fetch(Property): GetResponse - + fetch(T, Collection) + + fetch(T, Collection) + update(Property, Datapoint): SetResponse - + update(VssSpecification, Collection): SetResponse + + update(VssNode, Collection): SetResponse + disconnect() } diff --git a/docs/kuksa-vss-core_class-diagram.puml b/docs/kuksa-vss-core_class-diagram.puml index 5683f953..b6856aee 100644 --- a/docs/kuksa-vss-core_class-diagram.puml +++ b/docs/kuksa-vss-core_class-diagram.puml @@ -3,19 +3,13 @@ !startsub VssCore package VssCore { - VssNode <|- VssSpecification - VssSpecification <|- VssProperty + VssNode <|- VssLeaf - annotation VssDefinition { - + vssDefinitionPath: String - } + annotation VssModelGenerator interface VssNode { - + children: Set + + children: Set + parentClass: KClass<*> - } - - interface VssSpecification { + uuid: String + vssPath: String + description: String @@ -23,7 +17,7 @@ package VssCore { + comment: String } - interface VssProperty { + interface VssLeaf { + value: T } } diff --git a/docs/kuksa-vss-processor_class-diagram.puml b/docs/kuksa-vss-processor_class-diagram.puml index 98845f48..7cd61c5b 100644 --- a/docs/kuksa-vss-processor_class-diagram.puml +++ b/docs/kuksa-vss-processor_class-diagram.puml @@ -4,39 +4,39 @@ !includesub kuksa-vss-core_class-diagram.puml!VssCore package App { - MainActivity --o VssDefinition + MainActivity --o VssModelGenerator class MainActivity } package VssProcessor { - VssDefinitionProcessor -down-> VssDefinitionVisitor - VssDefinitionProcessor -down-> VssDefinitionParser - VssDefinitionProcessor -down-> SpecModel - VssDefinitionParser <|- YamlDefinitionParser - SpecModel <|- VssSpecificationSpecModel - VssSpecification <|- VssSpecificationSpecModel + VssModelGeneratorProcessor -down-> VssModelGeneratorVisitor + VssModelGeneratorProcessor -down-> VssParser + VssModelGeneratorProcessor -down-> SpecModel + VssParser <|- YamlVssParser + SpecModel <|- VssNodeSpecModel + VssNode <|-- VssNodeSpecModel - class VssDefinitionProcessor { - + VssDefinitionProcessor(CodeGenerator, KSPLogger) + class VssModelGeneratorProcessor { + + VssModelGeneratorProcessor(CodeGenerator, KSPLogger) } - class VssDefinitionVisitor { + class VssModelGeneratorVisitor { + visitClassDeclaration(KSClassDeclaration) } - interface VssDefinitionParser { - + parseSpecifications(File, elementDelimiter: String,): Collection + interface VssParser { + + parseNodes(File, elementDelimiter: String,): Collection } - class YamlDefinitionParser + class YamlVssParser interface SpecModel> { - + createClassSpec(packageName: String, relatedSpecifications: Collection, nestedClasses: Collection): TypeSpec + + createClassSpec(packageName: String, relatedNodes: Collection, nestedClasses: Collection): TypeSpec } - class VssSpecificationSpecModel { + class VssNodeSpecModel { } } diff --git a/kuksa-sdk/src/main/kotlin/org/eclipse/kuksa/DataBrokerConnection.kt b/kuksa-sdk/src/main/kotlin/org/eclipse/kuksa/DataBrokerConnection.kt index 20884620..4e31ff47 100644 --- a/kuksa-sdk/src/main/kotlin/org/eclipse/kuksa/DataBrokerConnection.kt +++ b/kuksa-sdk/src/main/kotlin/org/eclipse/kuksa/DataBrokerConnection.kt @@ -112,7 +112,7 @@ class DataBrokerConnection internal constructor( } /** - * Subscribes to the specified [VssNode] with the provided [VssSpecificationListener]. Only a [VssLeaf] + * Subscribes to the specified [VssNode] with the provided [VssNodeListener]. Only a [VssLeaf] * can be subscribed because they have an actual value. When provided with any parent [VssNode] then this * [subscribe] method will find all [VssLeaf] children and subscribes them instead. Once subscribed the * application will be notified about any changes to every subscribed [VssLeaf]. The [fields] can be used to @@ -125,7 +125,7 @@ class DataBrokerConnection internal constructor( fun subscribe( specification: T, fields: Collection = listOf(Field.FIELD_VALUE), - listener: VssSpecificationListener, + listener: VssNodeListener, ) { fields.forEach { field -> dataBrokerSubscriber.subscribe(specification, field, listener) @@ -138,7 +138,7 @@ class DataBrokerConnection internal constructor( fun unsubscribe( specification: T, fields: Collection = listOf(Field.FIELD_VALUE), - listener: VssSpecificationListener, + listener: VssNodeListener, ) { fields.forEach { field -> dataBrokerSubscriber.unsubscribe(specification, field, listener) @@ -221,12 +221,12 @@ class DataBrokerConnection internal constructor( */ @JvmOverloads suspend fun update( - vssSpecification: VssNode, + vssNode: VssNode, fields: Collection = listOf(Field.FIELD_VALUE), ): Collection { val responses = mutableListOf() - vssSpecification.vssProperties.forEach { vssProperty -> + vssNode.vssProperties.forEach { vssProperty -> val property = Property(vssProperty.vssPath, fields) val response = update(property, vssProperty.datapoint) responses.add(response) diff --git a/kuksa-sdk/src/main/kotlin/org/eclipse/kuksa/PropertyListener.kt b/kuksa-sdk/src/main/kotlin/org/eclipse/kuksa/PropertyListener.kt index fc59de37..9fc9a9c8 100644 --- a/kuksa-sdk/src/main/kotlin/org/eclipse/kuksa/PropertyListener.kt +++ b/kuksa-sdk/src/main/kotlin/org/eclipse/kuksa/PropertyListener.kt @@ -42,14 +42,14 @@ interface PropertyListener : Listener { /** * The Listener is used to notify about subscribed [VssNode]. If a [VssNode] has children - * then [onSpecificationChanged] will be called on every value change for every children. + * then [onNodeChanged] will be called on every value change for every children. */ -interface VssSpecificationListener { +interface VssNodeListener { /** - * Will be triggered with the [vssSpecification] when the underlying vssPath changed it's value or to inform about + * Will be triggered with the [vssNode] when the underlying vssPath changed it's value or to inform about * the initial state. */ - fun onSpecificationChanged(vssSpecification: T) + fun onNodeChanged(vssNode: T) /** * Will be triggered when an error happens during subscription and forwards the [throwable]. diff --git a/kuksa-sdk/src/main/kotlin/org/eclipse/kuksa/extension/VssSpecificationCopyExtension.kt b/kuksa-sdk/src/main/kotlin/org/eclipse/kuksa/extension/VssSpecificationCopyExtension.kt index eeaf7fb5..04da6128 100644 --- a/kuksa-sdk/src/main/kotlin/org/eclipse/kuksa/extension/VssSpecificationCopyExtension.kt +++ b/kuksa-sdk/src/main/kotlin/org/eclipse/kuksa/extension/VssSpecificationCopyExtension.kt @@ -55,7 +55,7 @@ fun T.deepCopy(generation: Int = 0, vararg changedHeritage: VssNod return this } - // Create the missing link between this (VssSpecification) and the given property (VssSpecifications inbetween) + // Create the missing link between this [VssNode] and the given property (node inbetween) var heritageLine = changedHeritage if (changedHeritage.size == 1) { heritageLine = findHeritageLine(changedHeritage.first(), true) @@ -153,8 +153,8 @@ fun T.copy( updatedValue: Datapoint, consideredHeritage: Collection = heritage, ): T { - val vssSpecifications = consideredHeritage + this - val vssProperty = vssSpecifications + val vssNodes = consideredHeritage + this + val vssProperty = vssNodes .filterIsInstance>() .find { it.vssPath == vssPath } ?: return this diff --git a/kuksa-sdk/src/main/kotlin/org/eclipse/kuksa/subscription/DataBrokerSubscriber.kt b/kuksa-sdk/src/main/kotlin/org/eclipse/kuksa/subscription/DataBrokerSubscriber.kt index 8c38a0cc..c4fb2035 100644 --- a/kuksa-sdk/src/main/kotlin/org/eclipse/kuksa/subscription/DataBrokerSubscriber.kt +++ b/kuksa-sdk/src/main/kotlin/org/eclipse/kuksa/subscription/DataBrokerSubscriber.kt @@ -23,7 +23,7 @@ import android.util.Log import org.eclipse.kuksa.DataBrokerException import org.eclipse.kuksa.DataBrokerTransporter import org.eclipse.kuksa.PropertyListener -import org.eclipse.kuksa.VssSpecificationListener +import org.eclipse.kuksa.VssNodeListener import org.eclipse.kuksa.extension.TAG import org.eclipse.kuksa.proto.v1.Types import org.eclipse.kuksa.proto.v1.Types.Field @@ -76,7 +76,7 @@ internal class DataBrokerSubscriber(private val dataBrokerTransporter: DataBroke } /** - * Subscribes to the specified [VssNode] with the provided [VssSpecificationListener]. Only a [VssLeaf] + * Subscribes to the specified [VssNode] with the provided [VssNodeListener]. Only a [VssLeaf] * can be subscribed because they have an actual value. When provided with any parent [VssNode] then this * [subscribe] method will find all [VssLeaf] children and subscribes them instead. Once subscribed the * application will be notified about any changes to every subscribed [VssLeaf]. The [field] can be used to @@ -88,7 +88,7 @@ internal class DataBrokerSubscriber(private val dataBrokerTransporter: DataBroke fun subscribe( specification: T, field: Field = Field.FIELD_VALUE, - listener: VssSpecificationListener, + listener: VssNodeListener, ) { val vssPath = specification.vssPath @@ -105,7 +105,7 @@ internal class DataBrokerSubscriber(private val dataBrokerTransporter: DataBroke fun unsubscribe( specification: T, field: Field = Field.FIELD_VALUE, - listener: VssSpecificationListener, + listener: VssNodeListener, ) { val vssPath = specification.vssPath diff --git a/kuksa-sdk/src/main/kotlin/org/eclipse/kuksa/subscription/SpecificationPropertyListener.kt b/kuksa-sdk/src/main/kotlin/org/eclipse/kuksa/subscription/SpecificationPropertyListener.kt index 5f46bd4a..0eb0780f 100644 --- a/kuksa-sdk/src/main/kotlin/org/eclipse/kuksa/subscription/SpecificationPropertyListener.kt +++ b/kuksa-sdk/src/main/kotlin/org/eclipse/kuksa/subscription/SpecificationPropertyListener.kt @@ -20,26 +20,26 @@ package org.eclipse.kuksa.subscription import org.eclipse.kuksa.PropertyListener -import org.eclipse.kuksa.VssSpecificationListener +import org.eclipse.kuksa.VssNodeListener import org.eclipse.kuksa.extension.copy import org.eclipse.kuksa.proto.v1.KuksaValV1 import org.eclipse.kuksa.vsscore.model.VssNode internal class SpecificationPropertyListener( - specification: T, - private val listener: VssSpecificationListener, + node: T, + private val listener: VssNodeListener, ) : PropertyListener { // This is currently needed because we get multiple subscribe responses for every heir. Otherwise we // would override the last heir value with every new response. - private var updatedVssSpecification: T = specification + private var updatedVssNode: T = node override fun onPropertyChanged(entryUpdates: List) { entryUpdates.forEach { entryUpdate -> val dataEntry = entryUpdate.entry - updatedVssSpecification = updatedVssSpecification.copy(dataEntry.path, dataEntry.value) + updatedVssNode = updatedVssNode.copy(dataEntry.path, dataEntry.value) } - listener.onSpecificationChanged(updatedVssSpecification) + listener.onNodeChanged(updatedVssNode) } override fun onError(throwable: Throwable) { diff --git a/samples/src/main/java/com/example/sample/JavaActivity.java b/samples/src/main/java/com/example/sample/JavaActivity.java index 1ef1dd08..d2bded31 100644 --- a/samples/src/main/java/com/example/sample/JavaActivity.java +++ b/samples/src/main/java/com/example/sample/JavaActivity.java @@ -27,7 +27,7 @@ import org.eclipse.kuksa.DataBrokerConnector; import org.eclipse.kuksa.DisconnectListener; import org.eclipse.kuksa.PropertyListener; -import org.eclipse.kuksa.VssSpecificationListener; +import org.eclipse.kuksa.VssNodeListener; import org.eclipse.kuksa.authentication.JsonWebToken; import org.eclipse.kuksa.model.Property; import org.eclipse.kuksa.proto.v1.KuksaValV1; @@ -53,7 +53,7 @@ /** * @noinspection unused */ -//@VssDefinition // Commented out to prevent conflicts with the Kotlin activity +//@VssModelGenerator // Commented out to prevent conflicts with the Kotlin activity public class JavaActivity extends AppCompatActivity { private final DisconnectListener disconnectListener = () -> { @@ -245,10 +245,10 @@ public void subscribeSpecification() { dataBrokerConnection.subscribe( vssSpeed, Collections.singleton(Types.Field.FIELD_VALUE), - new VssSpecificationListener() { + new VssNodeListener() { @Override - public void onSpecificationChanged(@NonNull VssVehicle.VssSpeed vssSpecification) { - Float speed = vssSpecification.getValue(); + public void onNodeChanged(@NonNull VssVehicle.VssSpeed vssNode) { + Float speed = vssNode.getValue(); } @Override diff --git a/samples/src/main/kotlin/com/example/sample/KotlinActivity.kt b/samples/src/main/kotlin/com/example/sample/KotlinActivity.kt index 12536968..c21c1f7f 100644 --- a/samples/src/main/kotlin/com/example/sample/KotlinActivity.kt +++ b/samples/src/main/kotlin/com/example/sample/KotlinActivity.kt @@ -31,18 +31,18 @@ import org.eclipse.kuksa.DataBrokerConnector import org.eclipse.kuksa.DataBrokerException import org.eclipse.kuksa.DisconnectListener import org.eclipse.kuksa.PropertyListener -import org.eclipse.kuksa.VssSpecificationListener +import org.eclipse.kuksa.VssNodeListener import org.eclipse.kuksa.authentication.JsonWebToken import org.eclipse.kuksa.model.Property import org.eclipse.kuksa.proto.v1.KuksaValV1 import org.eclipse.kuksa.proto.v1.Types import org.eclipse.kuksa.proto.v1.Types.Datapoint import org.eclipse.kuksa.vss.VssVehicle -import org.eclipse.kuksa.vsscore.annotation.VssDefinition +import org.eclipse.kuksa.vsscore.annotation.VssModelGenerator import java.io.IOException @Suppress("UNUSED_VARIABLE", "SwallowedException") -@VssDefinition +@VssModelGenerator class KotlinActivity : AppCompatActivity() { private var disconnectListener = DisconnectListener { @@ -184,8 +184,8 @@ class KotlinActivity : AppCompatActivity() { dataBrokerConnection?.subscribe( vssSpeed, listOf(Types.Field.FIELD_VALUE), - listener = object : VssSpecificationListener { - override fun onSpecificationChanged(vssSpecification: VssVehicle.VssSpeed) { + listener = object : VssNodeListener { + override fun onNodeChanged(vssNode: VssVehicle.VssSpeed) { val speed = vssSpeed.value } diff --git a/vss-core/src/main/java/org/eclipse/kuksa/vsscore/annotation/VssDefinition.kt b/vss-core/src/main/java/org/eclipse/kuksa/vsscore/annotation/VssModelGenerator.kt similarity index 88% rename from vss-core/src/main/java/org/eclipse/kuksa/vsscore/annotation/VssDefinition.kt rename to vss-core/src/main/java/org/eclipse/kuksa/vsscore/annotation/VssModelGenerator.kt index 1098bb86..c5ef696d 100644 --- a/vss-core/src/main/java/org/eclipse/kuksa/vsscore/annotation/VssDefinition.kt +++ b/vss-core/src/main/java/org/eclipse/kuksa/vsscore/annotation/VssModelGenerator.kt @@ -21,8 +21,8 @@ package org.eclipse.kuksa.vsscore.annotation /** * Add this annotation to any class to trigger the model generation (Kotlin Symbol Processing) for the given - * Vehicle Signal Specification definition file by the "vss-processor-plugin". Only .yaml files are currently supported. - * Use the "VSS Processor Plugin" to provide the Symbol Processor with the necessary definition file(s). + * Vehicle Signal Specification file by the "vss-processor-plugin". Only .yaml files are currently supported. + * Use the "VSS Processor Plugin" to provide the Symbol Processor with the necessary VSS file(s). * * ### Plugin Example * @@ -41,7 +41,7 @@ package org.eclipse.kuksa.vsscore.annotation * ### Annotation Example * * ``` - * @VssDefinition + * @VssModelGenerator * class Activity * ``` * @@ -55,4 +55,4 @@ package org.eclipse.kuksa.vsscore.annotation */ @Target(AnnotationTarget.CLASS) @Retention(AnnotationRetention.SOURCE) -annotation class VssDefinition +annotation class VssModelGenerator diff --git a/vss-processor-plugin/src/main/java/org/eclipse/kuksa/vssprocessor/plugin/VssProcessorPlugin.kt b/vss-processor-plugin/src/main/java/org/eclipse/kuksa/vssprocessor/plugin/VssProcessorPlugin.kt index 6dc4f9bc..2a119a17 100644 --- a/vss-processor-plugin/src/main/java/org/eclipse/kuksa/vssprocessor/plugin/VssProcessorPlugin.kt +++ b/vss-processor-plugin/src/main/java/org/eclipse/kuksa/vssprocessor/plugin/VssProcessorPlugin.kt @@ -67,15 +67,15 @@ class VssProcessorPlugin : Plugin { val buildDirPath = buildDir.absolutePath val vssDir = "${rootDir}${fileSeparator}$VSS_FOLDER_NAME" - val provideVssDefinitionTask = - project.tasks.register(PROVIDE_VSS_DEFINITION_TASK_NAME) { + val provideVssFilesTask = + project.tasks.register(PROVIDE_VSS_FILES_TASK_NAME) { val searchPath = extension.searchPath.get().ifEmpty { vssDir } - val vssDefinitionFilePath = StringBuilder(buildDirPath) + val vssFilePath = StringBuilder(buildDirPath) .append(fileSeparator) .append(KSP_INPUT_BUILD_DIRECTORY) .append(fileSeparator) .toString() - val vssDefinitionBuildFile = File(vssDefinitionFilePath) + val vssBuildFile = File(vssFilePath) logger.info("Searching directory $searchPath for VSS definitions") @@ -88,11 +88,11 @@ class VssProcessorPlugin : Plugin { } inputDir.set(searchDir) - outputDir.set(vssDefinitionBuildFile) + outputDir.set(vssBuildFile) } tasks.getByName("preBuild").dependsOn( - provideVssDefinitionTask.get(), + provideVssFilesTask.get(), ) } } @@ -100,17 +100,17 @@ class VssProcessorPlugin : Plugin { companion object { private const val KSP_INPUT_BUILD_DIRECTORY = "kspInput" private const val EXTENSION_NAME = "vssProcessor" - private const val PROVIDE_VSS_DEFINITION_TASK_NAME = "provideVssDefinition" + private const val PROVIDE_VSS_FILES_TASK_NAME = "provideVssFiles" private const val VSS_FOLDER_NAME = "vss" } } /** - * This task takes an input directory [inputDir] which should contain all available VSS definition files and an + * This task takes an input directory [inputDir] which should contain all available VSS files and an * output directory [outputDir] where all files are copied to so the VSSProcessor can work with them. */ @CacheableTask -private abstract class ProvideVssDefinitionTask : DefaultTask() { +private abstract class ProvideVssFilesTask : DefaultTask() { @get:Incremental @get:IgnoreEmptyDirectories @get:PathSensitive(PathSensitivity.NAME_ONLY) diff --git a/vss-processor-plugin/src/test/kotlin/org/eclipse/kuksa/vssprocessor/plugin/VssProcessorPluginTest.kt b/vss-processor-plugin/src/test/kotlin/org/eclipse/kuksa/vssprocessor/plugin/VssProcessorPluginTest.kt index 5dbd4a45..42db208c 100644 --- a/vss-processor-plugin/src/test/kotlin/org/eclipse/kuksa/vssprocessor/plugin/VssProcessorPluginTest.kt +++ b/vss-processor-plugin/src/test/kotlin/org/eclipse/kuksa/vssprocessor/plugin/VssProcessorPluginTest.kt @@ -75,13 +75,13 @@ class VssProcessorPluginTest : BehaviorSpec({ pluginProject.refresh() // So the plugin project does not have 2 :lib includes } - `when`("the ProvideVssDefinitionTask is executed without correct input") { + `when`("the provideVssFiles task is executed without correct input") { val result = gradleRunner - .withArguments("provideVssDefinition") + .withArguments(PROVIDE_VSS_FILES_TASK_NAME) .buildAndFail() then("it should throw an Exception") { - result.output shouldContain "Could not create task ':lib:provideVssDefinition'" + result.output shouldContain "Could not create task ':lib:provideVssFiles'" } } } @@ -104,46 +104,46 @@ class VssProcessorPluginTest : BehaviorSpec({ pluginProject.add(vssProcessorProject) - `when`("the ProvideVssDefinitionTask is executed with build cache the #1 time") { + `when`("the provideVssFiles task is executed with build cache the #1 time") { pluginProject.localCacheFolder.deleteRecursively() val result = gradleRunner - .withArguments("clean", "--build-cache", "provideVssDefinition") + .withArguments("clean", "--build-cache", PROVIDE_VSS_FILES_TASK_NAME) .build() - println("ProvideVssDefinitionTask + Build Cache #1 output: ${result.output}") + println("ProvideVssFilesTask + Build Cache #1 output: ${result.output}") then("it should build successfully") { - val outcome = result.task(":lib:provideVssDefinition")?.outcome + val outcome = result.task(":lib:$PROVIDE_VSS_FILES_TASK_NAME")?.outcome outcome shouldBe TaskOutcome.SUCCESS } } - `when`("the ProvideVssDefinitionTask is executed with build cache the #2 time") { + `when`("the provideVssFiles task is executed with build cache the #2 time") { val result = gradleRunner - .withArguments("clean", "--build-cache", "provideVssDefinition") + .withArguments("clean", "--build-cache", PROVIDE_VSS_FILES_TASK_NAME) .build() - println("ProvideVssDefinitionTask + Build Cache #2 output: ${result.output}") + println("ProvideVssFilesTask + Build Cache #2 output: ${result.output}") then("it should build from cache") { - val outcome = result.task(":lib:provideVssDefinition")?.outcome + val outcome = result.task(":lib:$PROVIDE_VSS_FILES_TASK_NAME")?.outcome outcome shouldBe TaskOutcome.FROM_CACHE } } - `when`("the ProvideVssDefinitionTask is executed with build cache the #3 time") { + `when`("the provideVssFiles task is executed with build cache the #3 time") { val kspInputDir = vssProcessorProject.buildDir.resolve(KSP_INPUT_BUILD_DIRECTORY) val result = gradleRunner - .withArguments("--build-cache", "provideVssDefinition") + .withArguments("--build-cache", PROVIDE_VSS_FILES_TASK_NAME) .build() - println("ProvideVssDefinitionTask + Build Cache #3 output: ${result.output}") + println("ProvideVssFilesTask + Build Cache #3 output: ${result.output}") then("it should be up to date") { - val outcome = result.task(":lib:provideVssDefinition")?.outcome + val outcome = result.task(":lib:$PROVIDE_VSS_FILES_TASK_NAME")?.outcome outcome shouldBe TaskOutcome.UP_TO_DATE } @@ -155,7 +155,7 @@ class VssProcessorPluginTest : BehaviorSpec({ } } - `when`("the input of the ProvideVssDefinitionTask changes") { + `when`("the input of the ProvideVssFilesTask changes") { val projectVssDir2 = vssDir2Path.substringAfter(TEST_FOLDER_NAME_DEFAULT) vssProcessorProject.generate( """ @@ -166,28 +166,28 @@ class VssProcessorPluginTest : BehaviorSpec({ ) val result = gradleRunner - .withArguments("--build-cache", "provideVssDefinition") + .withArguments("--build-cache", PROVIDE_VSS_FILES_TASK_NAME) .build() - println("ProvideVssDefinitionTask + Build Cache #4 output: ${result.output}") + println("ProvideVssFilesTask + Build Cache #4 output: ${result.output}") then("it should build successfully") { - val outcome = result.task(":lib:provideVssDefinition")?.outcome + val outcome = result.task(":lib:$PROVIDE_VSS_FILES_TASK_NAME")?.outcome outcome shouldBe TaskOutcome.SUCCESS } } - `when`("the name of the input of the ProvideVssDefinitionTask changes") { + `when`("the name of the input of the ProvideVssFilesTask changes") { vssFile2.renameTo(File("$vssDir2Path/vss_rel_4.0_test_renamed.yml")) val result = gradleRunner - .withArguments("--build-cache", "provideVssDefinition") + .withArguments("--build-cache", PROVIDE_VSS_FILES_TASK_NAME) .build() - println("ProvideVssDefinitionTask + Build Cache #5 output: ${result.output}") + println("ProvideVssFilesTask + Build Cache #5 output: ${result.output}") then("it should build successfully") { - val outcome = result.task(":lib:provideVssDefinition")?.outcome + val outcome = result.task(":lib:$PROVIDE_VSS_FILES_TASK_NAME")?.outcome outcome shouldBe TaskOutcome.SUCCESS } @@ -198,6 +198,7 @@ class VssProcessorPluginTest : BehaviorSpec({ }) { companion object { private const val VSS_TEST_FILE_NAME = "vss_rel_4.0_test.yaml" + private const val PROVIDE_VSS_FILES_TASK_NAME = "provideVssFiles" private const val VSS_TEST_FILE_MINIMAL_NAME = "vss_rel_4.0_test_minimal.yaml" private const val GRADLE_VERSION_TEST = "8.6" private const val KSP_INPUT_BUILD_DIRECTORY = "kspInput" diff --git a/vss-processor/src/main/kotlin/org/eclipse/kuksa/vssprocessor/VssModelGeneratorProcessor.kt b/vss-processor/src/main/kotlin/org/eclipse/kuksa/vssprocessor/VssModelGeneratorProcessor.kt index 53d163d2..be4cee07 100644 --- a/vss-processor/src/main/kotlin/org/eclipse/kuksa/vssprocessor/VssModelGeneratorProcessor.kt +++ b/vss-processor/src/main/kotlin/org/eclipse/kuksa/vssprocessor/VssModelGeneratorProcessor.kt @@ -36,11 +36,11 @@ import com.google.devtools.ksp.validate import com.squareup.kotlinpoet.FileSpec import com.squareup.kotlinpoet.ksp.toClassName import com.squareup.kotlinpoet.ksp.writeTo -import org.eclipse.kuksa.vsscore.annotation.VssDefinition +import org.eclipse.kuksa.vsscore.annotation.VssModelGenerator import org.eclipse.kuksa.vsscore.model.parentClassName -import org.eclipse.kuksa.vssprocessor.parser.YamlDefinitionParser +import org.eclipse.kuksa.vssprocessor.parser.YamlVssParser +import org.eclipse.kuksa.vssprocessor.spec.VssNodeSpecModel import org.eclipse.kuksa.vssprocessor.spec.VssPath -import org.eclipse.kuksa.vssprocessor.spec.VssSpecificationSpecModel import java.io.File /** @@ -50,15 +50,15 @@ import java.io.File * @param codeGenerator to generate class files with * @param logger to log output with */ -class VssDefinitionProcessor( +class VssModelGeneratorProcessor( private val codeGenerator: CodeGenerator, private val logger: KSPLogger, ) : SymbolProcessor { - private val visitor = VssDefinitionVisitor() - private val yamlParser = YamlDefinitionParser() + private val visitor = VssModelGeneratorVisitor() + private val yamlParser = YamlVssParser() override fun process(resolver: Resolver): List { - val symbols = resolver.getSymbolsWithAnnotation(VssDefinition::class.qualifiedName.toString()) + val symbols = resolver.getSymbolsWithAnnotation(VssModelGenerator::class.qualifiedName.toString()) val deferredSymbols = symbols.filterNot { it.validate() } symbols.forEach { it.accept(visitor, Unit) } @@ -67,7 +67,7 @@ class VssDefinitionProcessor( return emptyList() } - private inner class VssDefinitionVisitor : KSVisitorVoid() { + private inner class VssModelGeneratorVisitor : KSVisitorVoid() { override fun visitClassDeclaration(classDeclaration: KSClassDeclaration, data: Unit) { val containingFile = classDeclaration.containingFile ?: return @@ -79,24 +79,24 @@ class VssDefinitionProcessor( annotatedProcessorFileName, ) - val definitionFiles = loadVssDefinitionFiles() - if (definitionFiles.isEmpty()) { - logger.error("No VSS definition files were found! Is the plugin correctly configured?") + val vssFiles = loadVssFiles() + if (vssFiles.isEmpty()) { + logger.error("No VSS files were found! Is the plugin correctly configured?") return } - definitionFiles.forEach { definitionFile -> - val simpleSpecificationElements = yamlParser.parseSpecifications(definitionFile) - val vssPathToSpecificationElement = simpleSpecificationElements + vssFiles.forEach { vssFile -> + val simpleVssNodeElements = yamlParser.parseNodes(vssFile) + val vssPathToVssNodeElement = simpleVssNodeElements .associateBy({ VssPath(it.vssPath) }, { it }) - logger.info("Generating models for definition file: ${definitionFile.name}") - generateModelFiles(vssPathToSpecificationElement) + logger.info("Generating models for VSS file: ${vssFile.name}") + generateModelFiles(vssPathToVssNodeElement) } } // Uses the default file path for generated files (from the code generator) and searches for the given file. - private fun loadVssDefinitionFiles(): Collection { + private fun loadVssFiles(): Collection { val generatedFile = codeGenerator.generatedFile.firstOrNull() ?: return emptySet() val generationPath = generatedFile.absolutePath val buildPath = generationPath.replaceAfterLast("$BUILD_FOLDER_NAME$fileSeparator", "") @@ -109,7 +109,7 @@ class VssDefinitionProcessor( .toSet() } - private fun generateModelFiles(vssPathToSpecification: Map) { + private fun generateModelFiles(vssPathToSpecification: Map) { val duplicateSpecificationNames = vssPathToSpecification.keys .groupBy { it.leaf } .filter { it.value.size > 1 } @@ -152,7 +152,7 @@ class VssDefinitionProcessor( // If the actual parent is a sub class (Driver) in another class file (e.g. Vehicle) then this method returns // a sub import e.g. "Vehicle.Driver". Otherwise just "Vehicle" is returned. private fun buildParentImport( - specModel: VssSpecificationSpecModel, + specModel: VssNodeSpecModel, parentVssPathToClassName: Map, ): String { var availableParentVssPath = specModel.vssPath @@ -193,12 +193,12 @@ class VssDefinitionProcessor( } /** - * Provides the environment for the [VssDefinitionProcessor]. + * Provides the environment for the [VssModelGeneratorProcessor]. */ -class VssDefinitionProcessorProvider : SymbolProcessorProvider { +class VssModelGeneratorProcessorProvider : SymbolProcessorProvider { override fun create( environment: SymbolProcessorEnvironment, ): SymbolProcessor { - return VssDefinitionProcessor(environment.codeGenerator, environment.logger) + return VssModelGeneratorProcessor(environment.codeGenerator, environment.logger) } } diff --git a/vss-processor/src/main/kotlin/org/eclipse/kuksa/vssprocessor/parser/VssParser.kt b/vss-processor/src/main/kotlin/org/eclipse/kuksa/vssprocessor/parser/VssParser.kt index 4949d476..04dcdd0e 100644 --- a/vss-processor/src/main/kotlin/org/eclipse/kuksa/vssprocessor/parser/VssParser.kt +++ b/vss-processor/src/main/kotlin/org/eclipse/kuksa/vssprocessor/parser/VssParser.kt @@ -22,12 +22,12 @@ package org.eclipse.kuksa.vssprocessor.parser import org.eclipse.kuksa.vssprocessor.spec.VssNodeSpecModel import java.io.File -internal interface VssDefinitionParser { +internal interface VssParser { /** * @param definitionFile to parse [VssNodeSpecModel] with * @param elementDelimiter which is the separator string between the specifications. The default is an empty line. */ - fun parseSpecifications( + fun parseNodes( definitionFile: File, elementDelimiter: String = "", ): List diff --git a/vss-processor/src/main/kotlin/org/eclipse/kuksa/vssprocessor/parser/YamlVssParser.kt b/vss-processor/src/main/kotlin/org/eclipse/kuksa/vssprocessor/parser/YamlVssParser.kt index 4e6811b2..705cc26d 100644 --- a/vss-processor/src/main/kotlin/org/eclipse/kuksa/vssprocessor/parser/YamlVssParser.kt +++ b/vss-processor/src/main/kotlin/org/eclipse/kuksa/vssprocessor/parser/YamlVssParser.kt @@ -26,8 +26,8 @@ import kotlin.reflect.KMutableProperty import kotlin.reflect.KProperty import kotlin.reflect.full.memberProperties -internal class YamlDefinitionParser : VssDefinitionParser { - override fun parseSpecifications(definitionFile: File, elementDelimiter: String): List { +internal class YamlVssParser : VssParser { + override fun parseNodes(definitionFile: File, elementDelimiter: String): List { val specificationElements = mutableListOf() definitionFile.useLines { lines -> val yamlAttributes = mutableListOf() diff --git a/vss-processor/src/main/kotlin/org/eclipse/kuksa/vssprocessor/spec/SpecModel.kt b/vss-processor/src/main/kotlin/org/eclipse/kuksa/vssprocessor/spec/SpecModel.kt index ecb3e0f3..facfd69d 100644 --- a/vss-processor/src/main/kotlin/org/eclipse/kuksa/vssprocessor/spec/SpecModel.kt +++ b/vss-processor/src/main/kotlin/org/eclipse/kuksa/vssprocessor/spec/SpecModel.kt @@ -28,14 +28,14 @@ import com.squareup.kotlinpoet.TypeSpec internal interface SpecModel> { /** * @param packageName to use for the generated class specs. - * @param relatedSpecifications which can be used to generate children dependencies for the current and all + * @param relatedNodes which can be used to generate children dependencies for the current and all * [nestedClasses] models. The information used are depended on [T]. * @param nestedClasses which can be used to create a class spec with nested classes. The string can be used as * identifier for finding the nested classes. */ fun createClassSpec( packageName: String, - relatedSpecifications: Collection = emptyList(), + relatedNodes: Collection = emptyList(), nestedClasses: Collection = emptySet(), ): TypeSpec } diff --git a/vss-processor/src/main/kotlin/org/eclipse/kuksa/vssprocessor/spec/VssNodeSpecModel.kt b/vss-processor/src/main/kotlin/org/eclipse/kuksa/vssprocessor/spec/VssNodeSpecModel.kt index 621505d3..9c03f7e6 100644 --- a/vss-processor/src/main/kotlin/org/eclipse/kuksa/vssprocessor/spec/VssNodeSpecModel.kt +++ b/vss-processor/src/main/kotlin/org/eclipse/kuksa/vssprocessor/spec/VssNodeSpecModel.kt @@ -45,14 +45,14 @@ import kotlin.reflect.full.declaredMemberProperties // Reflects the specification file as a model and is filled via reflection. That is why the variable names // should exactly match the names inside the specification file and be of a string type. -internal class VssSpecificationSpecModel( +internal class VssNodeSpecModel( override var uuid: String = "", override var vssPath: String = "", override var description: String = "", override var type: String = "", override var comment: String = "", @Suppress("MemberVisibilityCanBePrivate") var datatype: String = "", -) : VssNode, SpecModel { +) : VssNode, SpecModel { var logger: KSPLogger? = null private val stringTypeName = String::class.asTypeName() @@ -102,7 +102,7 @@ internal class VssSpecificationSpecModel( override fun createClassSpec( packageName: String, - relatedSpecifications: Collection, + relatedSpecifications: Collection, nestedClasses: Collection, ): TypeSpec { val childSpecifications = relatedSpecifications.filter { it.parentKey == name } @@ -143,7 +143,7 @@ internal class VssSpecificationSpecModel( val childPropertySpec = createVssNodeSpecs(className, uniquePackageName, childSpecification) propertySpecs.addAll(childPropertySpec) - // Nested VssSpecification properties should be added as constructor parameters + // Nested VssNode properties should be added as constructor parameters val mainClassPropertySpec = childPropertySpec.first() if (mainClassPropertySpec.initializer != null) { // Only add a default for initializer if (hasAmbiguousName) { @@ -213,7 +213,7 @@ internal class VssSpecificationSpecModel( private fun createVssNodeSpecs( className: String, packageName: String, - specification: VssSpecificationSpecModel = this, + specification: VssNodeSpecModel = this, ): List { val propertySpecs = mutableListOf() val members = VssNode::class.declaredMemberProperties @@ -235,7 +235,7 @@ internal class VssSpecificationSpecModel( } fun createObjectTypeSpec( - specification: VssSpecificationSpecModel, + specification: VssNodeSpecModel, packageName: String, ): PropertySpec { val prefixedTypeName = ClassName(packageName, specification.className) @@ -266,7 +266,7 @@ internal class VssSpecificationSpecModel( return listOf(objectTypeSpec) } - private fun createVssNodeTreeSpecs(childSpecifications: List): List { + private fun createVssNodeTreeSpecs(childSpecifications: List): List { fun createSetSpec(memberName: String, memberType: TypeName): PropertySpec { val specificationNamesJoined = childSpecifications.joinToString(", ") { it.variableName } @@ -314,7 +314,7 @@ internal class VssSpecificationSpecModel( } override fun equals(other: Any?): Boolean { - if (other !is VssSpecificationSpecModel) return false + if (other !is VssNodeSpecModel) return false return uuid == other.uuid } diff --git a/vss-processor/src/main/resources/META-INF/services/com.google.devtools.ksp.processing.SymbolProcessorProvider b/vss-processor/src/main/resources/META-INF/services/com.google.devtools.ksp.processing.SymbolProcessorProvider index ffd9900e..2c9bd87d 100644 --- a/vss-processor/src/main/resources/META-INF/services/com.google.devtools.ksp.processing.SymbolProcessorProvider +++ b/vss-processor/src/main/resources/META-INF/services/com.google.devtools.ksp.processing.SymbolProcessorProvider @@ -1 +1 @@ -org.eclipse.kuksa.vssprocessor.VssDefinitionProcessorProvider +org.eclipse.kuksa.vssprocessor.VssModelGeneratorProcessorProvider From 11fd90917553a95217b6bb2151b44b9f01bad377 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mark=20Hu=CC=88sers?= Date: Fri, 1 Mar 2024 12:54:43 +0100 Subject: [PATCH 07/20] chore: Sort DataBroker classes into packages --- .../databroker/JavaDataBrokerEngine.java | 12 +++--- .../kuksa/testapp/KuksaDataBrokerActivity.kt | 10 ++--- .../testapp/databroker/DataBrokerEngine.kt | 10 ++--- .../databroker/KotlinDataBrokerEngine.kt | 14 +++--- .../connection/DataBrokerConnectorFactory.kt | 6 +-- .../authentication/JsonWebToken.kt | 5 +-- .../authentication/VALStubExtension.kt | 5 +-- .../databroker}/DataBrokerConnection.kt | 10 +++-- .../databroker}/DataBrokerConnector.kt | 6 +-- .../databroker}/DataBrokerException.kt | 3 +- .../databroker}/DataBrokerTransporter.kt | 17 ++++---- .../listener}/DisconnectListener.kt | 6 +-- .../databroker/listener}/PropertyListener.kt | 3 +- .../subscription/DataBrokerSubscriber.kt | 23 +++++----- .../subscription/DataBrokerSubscription.kt} | 7 ++- .../SpecificationPropertyListener.kt | 7 ++- .../{ => coroutine}/CoroutineCallback.kt | 2 +- .../kuksa/{ => model}/TimeoutConfig.kt | 2 +- .../DataBrokerConnectorAuthenticationTest.kt | 6 +-- .../databroker/DataBrokerConfig.kt | 3 +- .../databroker}/DataBrokerConnectionTest.kt | 43 +++++++++---------- .../databroker/DataBrokerConnectorProvider.kt | 8 ++-- .../DataBrokerConnectorSecureTest.kt | 7 +-- .../databroker}/DataBrokerConnectorTest.kt | 4 +- .../databroker}/DataBrokerTransporterTest.kt | 11 ++--- .../subscription/DataBrokerSubscriberTest.kt | 11 +++-- .../DataBrokerTransporterExtensions.kt | 2 +- .../kuksa/mocking/FriendlyPropertyListener.kt | 2 +- .../kuksa/mocking/FriendlyVssNodeListener.kt | 2 +- .../java/com/example/sample/JavaActivity.java | 14 +++--- .../com/example/sample/KotlinActivity.kt | 14 +++--- 31 files changed, 126 insertions(+), 149 deletions(-) rename kuksa-sdk/src/main/kotlin/org/eclipse/kuksa/{ => connectivity}/authentication/JsonWebToken.kt (91%) rename kuksa-sdk/src/main/kotlin/org/eclipse/kuksa/{ => connectivity}/authentication/VALStubExtension.kt (93%) rename kuksa-sdk/src/main/kotlin/org/eclipse/kuksa/{ => connectivity/databroker}/DataBrokerConnection.kt (95%) rename kuksa-sdk/src/main/kotlin/org/eclipse/kuksa/{ => connectivity/databroker}/DataBrokerConnector.kt (95%) rename kuksa-sdk/src/main/kotlin/org/eclipse/kuksa/{ => connectivity/databroker}/DataBrokerException.kt (96%) rename kuksa-sdk/src/main/kotlin/org/eclipse/kuksa/{ => connectivity/databroker}/DataBrokerTransporter.kt (92%) rename kuksa-sdk/src/main/kotlin/org/eclipse/kuksa/{ => connectivity/databroker/listener}/DisconnectListener.kt (83%) rename kuksa-sdk/src/main/kotlin/org/eclipse/kuksa/{ => connectivity/databroker/listener}/PropertyListener.kt (97%) rename kuksa-sdk/src/main/kotlin/org/eclipse/kuksa/{ => connectivity/databroker}/subscription/DataBrokerSubscriber.kt (82%) rename kuksa-sdk/src/main/kotlin/org/eclipse/kuksa/{subscription/Subscription.kt => connectivity/databroker/subscription/DataBrokerSubscription.kt} (93%) rename kuksa-sdk/src/main/kotlin/org/eclipse/kuksa/{ => connectivity/databroker}/subscription/SpecificationPropertyListener.kt (90%) rename kuksa-sdk/src/main/kotlin/org/eclipse/kuksa/{ => coroutine}/CoroutineCallback.kt (97%) rename kuksa-sdk/src/main/kotlin/org/eclipse/kuksa/{ => model}/TimeoutConfig.kt (97%) rename kuksa-sdk/src/test/kotlin/org/eclipse/kuksa/{ => connectivity/authentication}/DataBrokerConnectorAuthenticationTest.kt (97%) rename kuksa-sdk/src/test/kotlin/org/eclipse/kuksa/{ => connectivity}/databroker/DataBrokerConfig.kt (95%) rename kuksa-sdk/src/test/kotlin/org/eclipse/kuksa/{ => connectivity/databroker}/DataBrokerConnectionTest.kt (88%) rename kuksa-sdk/src/test/kotlin/org/eclipse/kuksa/{ => connectivity}/databroker/DataBrokerConnectorProvider.kt (94%) rename kuksa-sdk/src/test/kotlin/org/eclipse/kuksa/{ => connectivity/databroker}/DataBrokerConnectorSecureTest.kt (88%) rename kuksa-sdk/src/test/kotlin/org/eclipse/kuksa/{ => connectivity/databroker}/DataBrokerConnectorTest.kt (95%) rename kuksa-sdk/src/test/kotlin/org/eclipse/kuksa/{ => connectivity/databroker}/DataBrokerTransporterTest.kt (94%) rename kuksa-sdk/src/test/kotlin/org/eclipse/kuksa/{ => connectivity/databroker}/subscription/DataBrokerSubscriberTest.kt (97%) diff --git a/app/src/main/java/org/eclipse/kuksa/testapp/databroker/JavaDataBrokerEngine.java b/app/src/main/java/org/eclipse/kuksa/testapp/databroker/JavaDataBrokerEngine.java index bef8af98..3702ecce 100644 --- a/app/src/main/java/org/eclipse/kuksa/testapp/databroker/JavaDataBrokerEngine.java +++ b/app/src/main/java/org/eclipse/kuksa/testapp/databroker/JavaDataBrokerEngine.java @@ -23,12 +23,12 @@ import androidx.annotation.NonNull; -import org.eclipse.kuksa.CoroutineCallback; -import org.eclipse.kuksa.DataBrokerConnection; -import org.eclipse.kuksa.DataBrokerConnector; -import org.eclipse.kuksa.DisconnectListener; -import org.eclipse.kuksa.PropertyListener; -import org.eclipse.kuksa.VssNodeListener; +import org.eclipse.kuksa.coroutine.CoroutineCallback; +import org.eclipse.kuksa.connectivity.databroker.DataBrokerConnection; +import org.eclipse.kuksa.connectivity.databroker.DataBrokerConnector; +import org.eclipse.kuksa.connectivity.databroker.listener.DisconnectListener; +import org.eclipse.kuksa.connectivity.databroker.listener.PropertyListener; +import org.eclipse.kuksa.connectivity.databroker.listener.VssNodeListener; import org.eclipse.kuksa.model.Property; import org.eclipse.kuksa.proto.v1.KuksaValV1.GetResponse; import org.eclipse.kuksa.proto.v1.KuksaValV1.SetResponse; diff --git a/app/src/main/kotlin/org/eclipse/kuksa/testapp/KuksaDataBrokerActivity.kt b/app/src/main/kotlin/org/eclipse/kuksa/testapp/KuksaDataBrokerActivity.kt index ff08c4c9..5b617530 100644 --- a/app/src/main/kotlin/org/eclipse/kuksa/testapp/KuksaDataBrokerActivity.kt +++ b/app/src/main/kotlin/org/eclipse/kuksa/testapp/KuksaDataBrokerActivity.kt @@ -29,11 +29,11 @@ import androidx.compose.material3.MaterialTheme import androidx.compose.material3.Surface import androidx.compose.ui.Modifier import androidx.lifecycle.lifecycleScope -import org.eclipse.kuksa.CoroutineCallback -import org.eclipse.kuksa.DataBrokerConnection -import org.eclipse.kuksa.DisconnectListener -import org.eclipse.kuksa.PropertyListener -import org.eclipse.kuksa.VssNodeListener +import org.eclipse.kuksa.coroutine.CoroutineCallback +import org.eclipse.kuksa.connectivity.databroker.DataBrokerConnection +import org.eclipse.kuksa.connectivity.databroker.listener.DisconnectListener +import org.eclipse.kuksa.connectivity.databroker.listener.PropertyListener +import org.eclipse.kuksa.connectivity.databroker.listener.VssNodeListener import org.eclipse.kuksa.extension.entriesMetadata import org.eclipse.kuksa.extension.valueType import org.eclipse.kuksa.model.Property diff --git a/app/src/main/kotlin/org/eclipse/kuksa/testapp/databroker/DataBrokerEngine.kt b/app/src/main/kotlin/org/eclipse/kuksa/testapp/databroker/DataBrokerEngine.kt index e4852237..2116dfa6 100644 --- a/app/src/main/kotlin/org/eclipse/kuksa/testapp/databroker/DataBrokerEngine.kt +++ b/app/src/main/kotlin/org/eclipse/kuksa/testapp/databroker/DataBrokerEngine.kt @@ -20,11 +20,11 @@ package org.eclipse.kuksa.testapp.databroker import android.content.Context -import org.eclipse.kuksa.CoroutineCallback -import org.eclipse.kuksa.DataBrokerConnection -import org.eclipse.kuksa.DisconnectListener -import org.eclipse.kuksa.PropertyListener -import org.eclipse.kuksa.VssNodeListener +import org.eclipse.kuksa.coroutine.CoroutineCallback +import org.eclipse.kuksa.connectivity.databroker.DataBrokerConnection +import org.eclipse.kuksa.connectivity.databroker.listener.DisconnectListener +import org.eclipse.kuksa.connectivity.databroker.listener.PropertyListener +import org.eclipse.kuksa.connectivity.databroker.listener.VssNodeListener import org.eclipse.kuksa.model.Property import org.eclipse.kuksa.proto.v1.KuksaValV1.GetResponse import org.eclipse.kuksa.proto.v1.KuksaValV1.SetResponse diff --git a/app/src/main/kotlin/org/eclipse/kuksa/testapp/databroker/KotlinDataBrokerEngine.kt b/app/src/main/kotlin/org/eclipse/kuksa/testapp/databroker/KotlinDataBrokerEngine.kt index cd8860f8..85097f86 100644 --- a/app/src/main/kotlin/org/eclipse/kuksa/testapp/databroker/KotlinDataBrokerEngine.kt +++ b/app/src/main/kotlin/org/eclipse/kuksa/testapp/databroker/KotlinDataBrokerEngine.kt @@ -22,13 +22,13 @@ package org.eclipse.kuksa.testapp.databroker import android.content.Context import androidx.lifecycle.LifecycleCoroutineScope import kotlinx.coroutines.launch -import org.eclipse.kuksa.CoroutineCallback -import org.eclipse.kuksa.DataBrokerConnection -import org.eclipse.kuksa.DataBrokerConnector -import org.eclipse.kuksa.DataBrokerException -import org.eclipse.kuksa.DisconnectListener -import org.eclipse.kuksa.PropertyListener -import org.eclipse.kuksa.VssNodeListener +import org.eclipse.kuksa.coroutine.CoroutineCallback +import org.eclipse.kuksa.connectivity.databroker.DataBrokerConnection +import org.eclipse.kuksa.connectivity.databroker.DataBrokerConnector +import org.eclipse.kuksa.connectivity.databroker.DataBrokerException +import org.eclipse.kuksa.connectivity.databroker.listener.DisconnectListener +import org.eclipse.kuksa.connectivity.databroker.listener.PropertyListener +import org.eclipse.kuksa.connectivity.databroker.listener.VssNodeListener import org.eclipse.kuksa.model.Property import org.eclipse.kuksa.proto.v1.KuksaValV1.GetResponse import org.eclipse.kuksa.proto.v1.KuksaValV1.SetResponse diff --git a/app/src/main/kotlin/org/eclipse/kuksa/testapp/databroker/connection/DataBrokerConnectorFactory.kt b/app/src/main/kotlin/org/eclipse/kuksa/testapp/databroker/connection/DataBrokerConnectorFactory.kt index 067b9162..895b6e1a 100644 --- a/app/src/main/kotlin/org/eclipse/kuksa/testapp/databroker/connection/DataBrokerConnectorFactory.kt +++ b/app/src/main/kotlin/org/eclipse/kuksa/testapp/databroker/connection/DataBrokerConnectorFactory.kt @@ -26,9 +26,9 @@ import io.grpc.Grpc import io.grpc.ManagedChannel import io.grpc.ManagedChannelBuilder import io.grpc.TlsChannelCredentials -import org.eclipse.kuksa.DataBrokerConnector -import org.eclipse.kuksa.TimeoutConfig -import org.eclipse.kuksa.authentication.JsonWebToken +import org.eclipse.kuksa.connectivity.databroker.DataBrokerConnector +import org.eclipse.kuksa.model.TimeoutConfig +import org.eclipse.kuksa.connectivity.authentication.JsonWebToken import org.eclipse.kuksa.testapp.databroker.model.ConnectionInfo import org.eclipse.kuksa.testapp.extension.readAsText import java.io.IOException diff --git a/kuksa-sdk/src/main/kotlin/org/eclipse/kuksa/authentication/JsonWebToken.kt b/kuksa-sdk/src/main/kotlin/org/eclipse/kuksa/connectivity/authentication/JsonWebToken.kt similarity index 91% rename from kuksa-sdk/src/main/kotlin/org/eclipse/kuksa/authentication/JsonWebToken.kt rename to kuksa-sdk/src/main/kotlin/org/eclipse/kuksa/connectivity/authentication/JsonWebToken.kt index a4c37603..5360b8b8 100644 --- a/kuksa-sdk/src/main/kotlin/org/eclipse/kuksa/authentication/JsonWebToken.kt +++ b/kuksa-sdk/src/main/kotlin/org/eclipse/kuksa/connectivity/authentication/JsonWebToken.kt @@ -1,5 +1,5 @@ /* - * Copyright (c) 2024 Contributors to the Eclipse Foundation + * Copyright (c) 2023 Contributors to the Eclipse Foundation * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -14,10 +14,9 @@ * limitations under the License. * * SPDX-License-Identifier: Apache-2.0 - * */ -package org.eclipse.kuksa.authentication +package org.eclipse.kuksa.connectivity.authentication /** * A JsonWebToken can be used to authenticate against the DataBroker. For authentication to work the DataBroker must be diff --git a/kuksa-sdk/src/main/kotlin/org/eclipse/kuksa/authentication/VALStubExtension.kt b/kuksa-sdk/src/main/kotlin/org/eclipse/kuksa/connectivity/authentication/VALStubExtension.kt similarity index 93% rename from kuksa-sdk/src/main/kotlin/org/eclipse/kuksa/authentication/VALStubExtension.kt rename to kuksa-sdk/src/main/kotlin/org/eclipse/kuksa/connectivity/authentication/VALStubExtension.kt index 7150f76b..be14d9bd 100644 --- a/kuksa-sdk/src/main/kotlin/org/eclipse/kuksa/authentication/VALStubExtension.kt +++ b/kuksa-sdk/src/main/kotlin/org/eclipse/kuksa/connectivity/authentication/VALStubExtension.kt @@ -1,5 +1,5 @@ /* - * Copyright (c) 2024 Contributors to the Eclipse Foundation + * Copyright (c) 2023 Contributors to the Eclipse Foundation * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -14,10 +14,9 @@ * limitations under the License. * * SPDX-License-Identifier: Apache-2.0 - * */ -package org.eclipse.kuksa.authentication +package org.eclipse.kuksa.connectivity.authentication import com.google.common.net.HttpHeaders import io.grpc.ClientInterceptor diff --git a/kuksa-sdk/src/main/kotlin/org/eclipse/kuksa/DataBrokerConnection.kt b/kuksa-sdk/src/main/kotlin/org/eclipse/kuksa/connectivity/databroker/DataBrokerConnection.kt similarity index 95% rename from kuksa-sdk/src/main/kotlin/org/eclipse/kuksa/DataBrokerConnection.kt rename to kuksa-sdk/src/main/kotlin/org/eclipse/kuksa/connectivity/databroker/DataBrokerConnection.kt index 4e31ff47..bd9ea303 100644 --- a/kuksa-sdk/src/main/kotlin/org/eclipse/kuksa/DataBrokerConnection.kt +++ b/kuksa-sdk/src/main/kotlin/org/eclipse/kuksa/connectivity/databroker/DataBrokerConnection.kt @@ -14,10 +14,9 @@ * limitations under the License. * * SPDX-License-Identifier: Apache-2.0 - * */ -package org.eclipse.kuksa +package org.eclipse.kuksa.connectivity.databroker import android.util.Log import io.grpc.ConnectivityState @@ -25,7 +24,11 @@ import io.grpc.ManagedChannel import kotlinx.coroutines.CoroutineDispatcher import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.withContext -import org.eclipse.kuksa.authentication.JsonWebToken +import org.eclipse.kuksa.connectivity.databroker.listener.DisconnectListener +import org.eclipse.kuksa.connectivity.databroker.listener.PropertyListener +import org.eclipse.kuksa.connectivity.databroker.listener.VssNodeListener +import org.eclipse.kuksa.connectivity.authentication.JsonWebToken +import org.eclipse.kuksa.connectivity.databroker.subscription.DataBrokerSubscriber import org.eclipse.kuksa.extension.TAG import org.eclipse.kuksa.extension.copy import org.eclipse.kuksa.extension.datapoint @@ -36,7 +39,6 @@ import org.eclipse.kuksa.proto.v1.KuksaValV1.SetResponse import org.eclipse.kuksa.proto.v1.Types import org.eclipse.kuksa.proto.v1.Types.Datapoint import org.eclipse.kuksa.proto.v1.Types.Field -import org.eclipse.kuksa.subscription.DataBrokerSubscriber import org.eclipse.kuksa.vsscore.model.VssLeaf import org.eclipse.kuksa.vsscore.model.VssNode import org.eclipse.kuksa.vsscore.model.heritage diff --git a/kuksa-sdk/src/main/kotlin/org/eclipse/kuksa/DataBrokerConnector.kt b/kuksa-sdk/src/main/kotlin/org/eclipse/kuksa/connectivity/databroker/DataBrokerConnector.kt similarity index 95% rename from kuksa-sdk/src/main/kotlin/org/eclipse/kuksa/DataBrokerConnector.kt rename to kuksa-sdk/src/main/kotlin/org/eclipse/kuksa/connectivity/databroker/DataBrokerConnector.kt index 9d885395..b4f83fb7 100644 --- a/kuksa-sdk/src/main/kotlin/org/eclipse/kuksa/DataBrokerConnector.kt +++ b/kuksa-sdk/src/main/kotlin/org/eclipse/kuksa/connectivity/databroker/DataBrokerConnector.kt @@ -14,10 +14,9 @@ * limitations under the License. * * SPDX-License-Identifier: Apache-2.0 - * */ -package org.eclipse.kuksa +package org.eclipse.kuksa.connectivity.databroker import android.util.Log import io.grpc.ConnectivityState @@ -26,7 +25,8 @@ import kotlinx.coroutines.CoroutineDispatcher import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.delay import kotlinx.coroutines.withContext -import org.eclipse.kuksa.authentication.JsonWebToken +import org.eclipse.kuksa.model.TimeoutConfig +import org.eclipse.kuksa.connectivity.authentication.JsonWebToken import org.eclipse.kuksa.extension.TAG /** diff --git a/kuksa-sdk/src/main/kotlin/org/eclipse/kuksa/DataBrokerException.kt b/kuksa-sdk/src/main/kotlin/org/eclipse/kuksa/connectivity/databroker/DataBrokerException.kt similarity index 96% rename from kuksa-sdk/src/main/kotlin/org/eclipse/kuksa/DataBrokerException.kt rename to kuksa-sdk/src/main/kotlin/org/eclipse/kuksa/connectivity/databroker/DataBrokerException.kt index 49edda33..e31cc12b 100644 --- a/kuksa-sdk/src/main/kotlin/org/eclipse/kuksa/DataBrokerException.kt +++ b/kuksa-sdk/src/main/kotlin/org/eclipse/kuksa/connectivity/databroker/DataBrokerException.kt @@ -14,10 +14,9 @@ * limitations under the License. * * SPDX-License-Identifier: Apache-2.0 - * */ -package org.eclipse.kuksa +package org.eclipse.kuksa.connectivity.databroker /** * An Exception which will be thrown when there are problems with the connection to the DataBroker. diff --git a/kuksa-sdk/src/main/kotlin/org/eclipse/kuksa/DataBrokerTransporter.kt b/kuksa-sdk/src/main/kotlin/org/eclipse/kuksa/connectivity/databroker/DataBrokerTransporter.kt similarity index 92% rename from kuksa-sdk/src/main/kotlin/org/eclipse/kuksa/DataBrokerTransporter.kt rename to kuksa-sdk/src/main/kotlin/org/eclipse/kuksa/connectivity/databroker/DataBrokerTransporter.kt index f6d3482b..b0f40816 100644 --- a/kuksa-sdk/src/main/kotlin/org/eclipse/kuksa/DataBrokerTransporter.kt +++ b/kuksa-sdk/src/main/kotlin/org/eclipse/kuksa/connectivity/databroker/DataBrokerTransporter.kt @@ -14,10 +14,9 @@ * limitations under the License. * * SPDX-License-Identifier: Apache-2.0 - * */ -package org.eclipse.kuksa +package org.eclipse.kuksa.connectivity.databroker import android.util.Log import io.grpc.ConnectivityState @@ -28,8 +27,8 @@ import io.grpc.stub.StreamObserver import kotlinx.coroutines.CoroutineDispatcher import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.withContext -import org.eclipse.kuksa.authentication.JsonWebToken -import org.eclipse.kuksa.authentication.withAuthenticationInterceptor +import org.eclipse.kuksa.connectivity.authentication.JsonWebToken +import org.eclipse.kuksa.connectivity.authentication.withAuthenticationInterceptor import org.eclipse.kuksa.extension.TAG import org.eclipse.kuksa.extension.applyDatapoint import org.eclipse.kuksa.proto.v1.KuksaValV1 @@ -37,12 +36,12 @@ import org.eclipse.kuksa.proto.v1.KuksaValV1.SubscribeResponse import org.eclipse.kuksa.proto.v1.Types import org.eclipse.kuksa.proto.v1.Types.Field import org.eclipse.kuksa.proto.v1.VALGrpc -import org.eclipse.kuksa.subscription.Subscription +import org.eclipse.kuksa.connectivity.databroker.subscription.DataBrokerSubscription /** * Encapsulates the Protobuf-specific interactions with the DataBroker send over gRPC. Provides fetch, update and * subscribe methods to retrieve and update data, as well as registering to be notified about external data updates - * using a [Subscription]. + * using a [DataBrokerSubscription]. * The DataBrokerTransporter requires a [managedChannel] which is already connected to the corresponding DataBroker. * * @throws IllegalStateException in case the state of the [managedChannel] is not [ConnectivityState.READY] @@ -135,7 +134,7 @@ internal class DataBrokerTransporter( /** * Sends a request to the DataBroker to subscribe to updates of the specified [vssPath] and [field]. - * Returns a [Subscription] which can be used to register or unregister additional listeners or cancel / closing + * Returns a [DataBrokerSubscription] which can be used to register or unregister additional listeners or cancel / closing * the subscription. * * @throws DataBrokerException in case the connection to the DataBroker is no longer active @@ -143,7 +142,7 @@ internal class DataBrokerTransporter( fun subscribe( vssPath: String, field: Field, - ): Subscription { + ): DataBrokerSubscription { val asyncStub = VALGrpc.newStub(managedChannel) val subscribeEntry = KuksaValV1.SubscribeEntry.newBuilder() @@ -158,7 +157,7 @@ internal class DataBrokerTransporter( val currentContext = Context.current() val cancellableContext = currentContext.withCancellation() - val subscription = Subscription(vssPath, field, cancellableContext) + val subscription = DataBrokerSubscription(vssPath, field, cancellableContext) val streamObserver = object : StreamObserver { override fun onNext(value: SubscribeResponse) { subscription.listeners.forEach { observer -> diff --git a/kuksa-sdk/src/main/kotlin/org/eclipse/kuksa/DisconnectListener.kt b/kuksa-sdk/src/main/kotlin/org/eclipse/kuksa/connectivity/databroker/listener/DisconnectListener.kt similarity index 83% rename from kuksa-sdk/src/main/kotlin/org/eclipse/kuksa/DisconnectListener.kt rename to kuksa-sdk/src/main/kotlin/org/eclipse/kuksa/connectivity/databroker/listener/DisconnectListener.kt index c61a5706..ae8e4fa5 100644 --- a/kuksa-sdk/src/main/kotlin/org/eclipse/kuksa/DisconnectListener.kt +++ b/kuksa-sdk/src/main/kotlin/org/eclipse/kuksa/connectivity/databroker/listener/DisconnectListener.kt @@ -14,15 +14,15 @@ * limitations under the License. * * SPDX-License-Identifier: Apache-2.0 - * */ -package org.eclipse.kuksa +package org.eclipse.kuksa.connectivity.databroker.listener import org.eclipse.kuksa.pattern.listener.Listener /** - * The [DisconnectListener] can be registered to [DataBrokerConnection.disconnectListeners] + * The [DisconnectListener] can be registered to + * [org.eclipse.kuksa.connectivity.databroker.DataBrokerConnection.disconnectListeners] * When registered it will notify about manual or unexpected connection disconnects from the DataBroker. */ fun interface DisconnectListener : Listener { diff --git a/kuksa-sdk/src/main/kotlin/org/eclipse/kuksa/PropertyListener.kt b/kuksa-sdk/src/main/kotlin/org/eclipse/kuksa/connectivity/databroker/listener/PropertyListener.kt similarity index 97% rename from kuksa-sdk/src/main/kotlin/org/eclipse/kuksa/PropertyListener.kt rename to kuksa-sdk/src/main/kotlin/org/eclipse/kuksa/connectivity/databroker/listener/PropertyListener.kt index 9fc9a9c8..37a2f2ac 100644 --- a/kuksa-sdk/src/main/kotlin/org/eclipse/kuksa/PropertyListener.kt +++ b/kuksa-sdk/src/main/kotlin/org/eclipse/kuksa/connectivity/databroker/listener/PropertyListener.kt @@ -14,10 +14,9 @@ * limitations under the License. * * SPDX-License-Identifier: Apache-2.0 - * */ -package org.eclipse.kuksa +package org.eclipse.kuksa.connectivity.databroker.listener import org.eclipse.kuksa.pattern.listener.Listener import org.eclipse.kuksa.proto.v1.KuksaValV1 diff --git a/kuksa-sdk/src/main/kotlin/org/eclipse/kuksa/subscription/DataBrokerSubscriber.kt b/kuksa-sdk/src/main/kotlin/org/eclipse/kuksa/connectivity/databroker/subscription/DataBrokerSubscriber.kt similarity index 82% rename from kuksa-sdk/src/main/kotlin/org/eclipse/kuksa/subscription/DataBrokerSubscriber.kt rename to kuksa-sdk/src/main/kotlin/org/eclipse/kuksa/connectivity/databroker/subscription/DataBrokerSubscriber.kt index c4fb2035..94c4e88d 100644 --- a/kuksa-sdk/src/main/kotlin/org/eclipse/kuksa/subscription/DataBrokerSubscriber.kt +++ b/kuksa-sdk/src/main/kotlin/org/eclipse/kuksa/connectivity/databroker/subscription/DataBrokerSubscriber.kt @@ -14,16 +14,15 @@ * limitations under the License. * * SPDX-License-Identifier: Apache-2.0 - * */ -package org.eclipse.kuksa.subscription +package org.eclipse.kuksa.connectivity.databroker.subscription import android.util.Log -import org.eclipse.kuksa.DataBrokerException -import org.eclipse.kuksa.DataBrokerTransporter -import org.eclipse.kuksa.PropertyListener -import org.eclipse.kuksa.VssNodeListener +import org.eclipse.kuksa.connectivity.databroker.listener.PropertyListener +import org.eclipse.kuksa.connectivity.databroker.listener.VssNodeListener +import org.eclipse.kuksa.connectivity.databroker.DataBrokerException +import org.eclipse.kuksa.connectivity.databroker.DataBrokerTransporter import org.eclipse.kuksa.extension.TAG import org.eclipse.kuksa.proto.v1.Types import org.eclipse.kuksa.proto.v1.Types.Field @@ -31,14 +30,14 @@ import org.eclipse.kuksa.vsscore.model.VssLeaf import org.eclipse.kuksa.vsscore.model.VssNode /** - * Creates [Subscription]s to the DataBroker to get notified about changes on the underlying vssPaths and fields. - * If no [Subscription] for a given vssPath and field does exist the DataBrokerSubscriber will create a new one. If it - * was already requested before, the same [Subscription] will be re-used. - * When the last [PropertyListener] of a [Subscription] unsubscribes the [Subscription] will be automatically canceled - * and removed from the active [Subscription]s. + * Creates [DataBrokerSubscription]s to the DataBroker to get notified about changes on the underlying vssPaths and fields. + * If no [DataBrokerSubscription] for a given vssPath and field does exist the DataBrokerSubscriber will create a new one. If it + * was already requested before, the same [DataBrokerSubscription] will be re-used. + * When the last [PropertyListener] of a [DataBrokerSubscription] unsubscribes the [DataBrokerSubscription] will be automatically canceled + * and removed from the active [DataBrokerSubscription]s. */ internal class DataBrokerSubscriber(private val dataBrokerTransporter: DataBrokerTransporter) { - private val subscriptions = mutableMapOf() // String(Subscription#identifier) -> Subscription + private val subscriptions = mutableMapOf() // String(Subscription#identifier) -> Subscription /** * Checks if the SDK is already subscribed to the corresponding [vssPath] and [field], if the SDK is already diff --git a/kuksa-sdk/src/main/kotlin/org/eclipse/kuksa/subscription/Subscription.kt b/kuksa-sdk/src/main/kotlin/org/eclipse/kuksa/connectivity/databroker/subscription/DataBrokerSubscription.kt similarity index 93% rename from kuksa-sdk/src/main/kotlin/org/eclipse/kuksa/subscription/Subscription.kt rename to kuksa-sdk/src/main/kotlin/org/eclipse/kuksa/connectivity/databroker/subscription/DataBrokerSubscription.kt index 6318bfab..a099badb 100644 --- a/kuksa-sdk/src/main/kotlin/org/eclipse/kuksa/subscription/Subscription.kt +++ b/kuksa-sdk/src/main/kotlin/org/eclipse/kuksa/connectivity/databroker/subscription/DataBrokerSubscription.kt @@ -14,13 +14,12 @@ * limitations under the License. * * SPDX-License-Identifier: Apache-2.0 - * */ -package org.eclipse.kuksa.subscription +package org.eclipse.kuksa.connectivity.databroker.subscription import io.grpc.Context -import org.eclipse.kuksa.PropertyListener +import org.eclipse.kuksa.connectivity.databroker.listener.PropertyListener import org.eclipse.kuksa.pattern.listener.MultiListener import org.eclipse.kuksa.proto.v1.KuksaValV1.SubscribeResponse import org.eclipse.kuksa.proto.v1.Types.Field @@ -35,7 +34,7 @@ import org.eclipse.kuksa.proto.v1.Types.Field * existing, resp. add the observer to the corresponding Subscription. If all Listeners are unregistered the * Subscription will be automatically canceled. */ -internal class Subscription( +internal class DataBrokerSubscription( val vssPath: String, val field: Field, private val cancellableContext: Context.CancellableContext, diff --git a/kuksa-sdk/src/main/kotlin/org/eclipse/kuksa/subscription/SpecificationPropertyListener.kt b/kuksa-sdk/src/main/kotlin/org/eclipse/kuksa/connectivity/databroker/subscription/SpecificationPropertyListener.kt similarity index 90% rename from kuksa-sdk/src/main/kotlin/org/eclipse/kuksa/subscription/SpecificationPropertyListener.kt rename to kuksa-sdk/src/main/kotlin/org/eclipse/kuksa/connectivity/databroker/subscription/SpecificationPropertyListener.kt index 0eb0780f..38e7540c 100644 --- a/kuksa-sdk/src/main/kotlin/org/eclipse/kuksa/subscription/SpecificationPropertyListener.kt +++ b/kuksa-sdk/src/main/kotlin/org/eclipse/kuksa/connectivity/databroker/subscription/SpecificationPropertyListener.kt @@ -14,13 +14,12 @@ * limitations under the License. * * SPDX-License-Identifier: Apache-2.0 - * */ -package org.eclipse.kuksa.subscription +package org.eclipse.kuksa.connectivity.databroker.subscription -import org.eclipse.kuksa.PropertyListener -import org.eclipse.kuksa.VssNodeListener +import org.eclipse.kuksa.connectivity.databroker.listener.PropertyListener +import org.eclipse.kuksa.connectivity.databroker.listener.VssNodeListener import org.eclipse.kuksa.extension.copy import org.eclipse.kuksa.proto.v1.KuksaValV1 import org.eclipse.kuksa.vsscore.model.VssNode diff --git a/kuksa-sdk/src/main/kotlin/org/eclipse/kuksa/CoroutineCallback.kt b/kuksa-sdk/src/main/kotlin/org/eclipse/kuksa/coroutine/CoroutineCallback.kt similarity index 97% rename from kuksa-sdk/src/main/kotlin/org/eclipse/kuksa/CoroutineCallback.kt rename to kuksa-sdk/src/main/kotlin/org/eclipse/kuksa/coroutine/CoroutineCallback.kt index 6f312508..cbaf40b1 100644 --- a/kuksa-sdk/src/main/kotlin/org/eclipse/kuksa/CoroutineCallback.kt +++ b/kuksa-sdk/src/main/kotlin/org/eclipse/kuksa/coroutine/CoroutineCallback.kt @@ -17,7 +17,7 @@ * */ -package org.eclipse.kuksa +package org.eclipse.kuksa.coroutine import kotlin.coroutines.Continuation import kotlin.coroutines.CoroutineContext diff --git a/kuksa-sdk/src/main/kotlin/org/eclipse/kuksa/TimeoutConfig.kt b/kuksa-sdk/src/main/kotlin/org/eclipse/kuksa/model/TimeoutConfig.kt similarity index 97% rename from kuksa-sdk/src/main/kotlin/org/eclipse/kuksa/TimeoutConfig.kt rename to kuksa-sdk/src/main/kotlin/org/eclipse/kuksa/model/TimeoutConfig.kt index 6956e47e..f1d0f02d 100644 --- a/kuksa-sdk/src/main/kotlin/org/eclipse/kuksa/TimeoutConfig.kt +++ b/kuksa-sdk/src/main/kotlin/org/eclipse/kuksa/model/TimeoutConfig.kt @@ -17,7 +17,7 @@ * */ -package org.eclipse.kuksa +package org.eclipse.kuksa.model import java.util.concurrent.TimeUnit import javax.annotation.concurrent.Immutable diff --git a/kuksa-sdk/src/test/kotlin/org/eclipse/kuksa/DataBrokerConnectorAuthenticationTest.kt b/kuksa-sdk/src/test/kotlin/org/eclipse/kuksa/connectivity/authentication/DataBrokerConnectorAuthenticationTest.kt similarity index 97% rename from kuksa-sdk/src/test/kotlin/org/eclipse/kuksa/DataBrokerConnectorAuthenticationTest.kt rename to kuksa-sdk/src/test/kotlin/org/eclipse/kuksa/connectivity/authentication/DataBrokerConnectorAuthenticationTest.kt index 74455579..168adf49 100644 --- a/kuksa-sdk/src/test/kotlin/org/eclipse/kuksa/DataBrokerConnectorAuthenticationTest.kt +++ b/kuksa-sdk/src/test/kotlin/org/eclipse/kuksa/connectivity/authentication/DataBrokerConnectorAuthenticationTest.kt @@ -14,14 +14,14 @@ * limitations under the License. * * SPDX-License-Identifier: Apache-2.0 - * */ -package org.eclipse.kuksa +package org.eclipse.kuksa.connectivity.authentication import io.kotest.core.spec.style.BehaviorSpec import io.kotest.matchers.shouldBe -import org.eclipse.kuksa.databroker.DataBrokerConnectorProvider +import org.eclipse.kuksa.connectivity.databroker.DataBrokerConnectionTest +import org.eclipse.kuksa.connectivity.databroker.DataBrokerConnectorProvider import org.eclipse.kuksa.model.Property import org.eclipse.kuksa.proto.v1.Types import org.eclipse.kuksa.test.kotest.Authentication diff --git a/kuksa-sdk/src/test/kotlin/org/eclipse/kuksa/databroker/DataBrokerConfig.kt b/kuksa-sdk/src/test/kotlin/org/eclipse/kuksa/connectivity/databroker/DataBrokerConfig.kt similarity index 95% rename from kuksa-sdk/src/test/kotlin/org/eclipse/kuksa/databroker/DataBrokerConfig.kt rename to kuksa-sdk/src/test/kotlin/org/eclipse/kuksa/connectivity/databroker/DataBrokerConfig.kt index 255e3d81..4c754649 100644 --- a/kuksa-sdk/src/test/kotlin/org/eclipse/kuksa/databroker/DataBrokerConfig.kt +++ b/kuksa-sdk/src/test/kotlin/org/eclipse/kuksa/connectivity/databroker/DataBrokerConfig.kt @@ -14,10 +14,9 @@ * limitations under the License. * * SPDX-License-Identifier: Apache-2.0 - * */ -package org.eclipse.kuksa.databroker +package org.eclipse.kuksa.connectivity.databroker import java.util.concurrent.TimeUnit diff --git a/kuksa-sdk/src/test/kotlin/org/eclipse/kuksa/DataBrokerConnectionTest.kt b/kuksa-sdk/src/test/kotlin/org/eclipse/kuksa/connectivity/databroker/DataBrokerConnectionTest.kt similarity index 88% rename from kuksa-sdk/src/test/kotlin/org/eclipse/kuksa/DataBrokerConnectionTest.kt rename to kuksa-sdk/src/test/kotlin/org/eclipse/kuksa/connectivity/databroker/DataBrokerConnectionTest.kt index c89c1fa9..6bd112d9 100644 --- a/kuksa-sdk/src/test/kotlin/org/eclipse/kuksa/DataBrokerConnectionTest.kt +++ b/kuksa-sdk/src/test/kotlin/org/eclipse/kuksa/connectivity/databroker/DataBrokerConnectionTest.kt @@ -14,10 +14,9 @@ * limitations under the License. * * SPDX-License-Identifier: Apache-2.0 - * */ -package org.eclipse.kuksa +package org.eclipse.kuksa.connectivity.databroker import io.grpc.ConnectivityState import io.grpc.ManagedChannel @@ -31,18 +30,16 @@ import io.mockk.mockk import io.mockk.slot import io.mockk.verify import kotlinx.coroutines.runBlocking -import org.eclipse.kuksa.databroker.DataBrokerConnectorProvider +import org.eclipse.kuksa.connectivity.databroker.listener.DisconnectListener +import org.eclipse.kuksa.connectivity.databroker.listener.PropertyListener import org.eclipse.kuksa.mocking.FriendlyVssNodeListener import org.eclipse.kuksa.model.Property import org.eclipse.kuksa.proto.v1.KuksaValV1 import org.eclipse.kuksa.proto.v1.Types -import org.eclipse.kuksa.proto.v1.Types.Datapoint import org.eclipse.kuksa.test.kotest.DefaultDatabroker import org.eclipse.kuksa.test.kotest.Integration import org.eclipse.kuksa.vssNode.VssDriver -import org.junit.jupiter.api.Assertions.assertEquals -import org.junit.jupiter.api.Assertions.assertFalse -import org.junit.jupiter.api.Assertions.assertTrue +import org.junit.jupiter.api.Assertions import kotlin.random.Random import kotlin.time.Duration.Companion.seconds @@ -77,7 +74,7 @@ class DataBrokerConnectionTest : BehaviorSpec({ val random = Random(System.currentTimeMillis()) val newValue = random.nextFloat() - val datapoint = Datapoint.newBuilder().setFloat(newValue).build() + val datapoint = Types.Datapoint.newBuilder().setFloat(newValue).build() dataBrokerConnection.update(property, datapoint) then("The #onPropertyChanged callback is triggered with the new value") { @@ -91,7 +88,7 @@ class DataBrokerConnectionTest : BehaviorSpec({ val capturedDatapoint = entryUpdates[0].entry.value val float = capturedDatapoint.float - assertEquals(newValue, float, 0.0001f) + Assertions.assertEquals(newValue, float, 0.0001f) } } } @@ -102,7 +99,7 @@ class DataBrokerConnectionTest : BehaviorSpec({ val response = dataBrokerConnection.update(property, validDatapoint) then("No error should appear") { - assertFalse(response.hasError()) + Assertions.assertFalse(response.hasError()) } and("When fetching it afterwards") { @@ -112,7 +109,7 @@ class DataBrokerConnectionTest : BehaviorSpec({ val entriesList = response1.entriesList val first = entriesList.first() val capturedValue = first.value - assertEquals(validDatapoint.float, capturedValue.float, 0.0001F) + Assertions.assertEquals(validDatapoint.float, capturedValue.float, 0.0001F) } } } @@ -123,7 +120,7 @@ class DataBrokerConnectionTest : BehaviorSpec({ then("It should fail with an errorCode 400 (type mismatch)") { val errorsList = response.errorsList - assertTrue(errorsList.size > 0) + Assertions.assertTrue(errorsList.size > 0) val error = errorsList[0].error @@ -137,7 +134,7 @@ class DataBrokerConnectionTest : BehaviorSpec({ val entriesList = getResponse.entriesList val first = entriesList.first() val capturedValue = first.value - assertEquals(validDatapoint.float, capturedValue.float, 0.0001F) + Assertions.assertEquals(validDatapoint.float, capturedValue.float, 0.0001F) } } } @@ -151,7 +148,7 @@ class DataBrokerConnectionTest : BehaviorSpec({ and("The initial value is different from the default for a child") { val newHeartRateValue = 60 - val datapoint = Datapoint.newBuilder().setUint32(newHeartRateValue).build() + val datapoint = Types.Datapoint.newBuilder().setUint32(newHeartRateValue).build() dataBrokerConnection.update(property, datapoint) @@ -176,7 +173,7 @@ class DataBrokerConnectionTest : BehaviorSpec({ and("The initial value is different from the default for a child") { val newHeartRateValue = 70 - val datapoint = Datapoint.newBuilder().setUint32(newHeartRateValue).build() + val datapoint = Types.Datapoint.newBuilder().setUint32(newHeartRateValue).build() dataBrokerConnection.update(property, datapoint) @@ -194,7 +191,7 @@ class DataBrokerConnectionTest : BehaviorSpec({ and("Any subscribed Property was changed") { val newHeartRateValue = 50 - val datapoint = Datapoint.newBuilder().setUint32(newHeartRateValue).build() + val datapoint = Types.Datapoint.newBuilder().setUint32(newHeartRateValue).build() dataBrokerConnection.update(property, datapoint) @@ -235,7 +232,7 @@ class DataBrokerConnectionTest : BehaviorSpec({ then("It should fail with an errorCode 404 (path not found)") { val errorsList = response.errorsList - assertTrue(errorsList.size > 0) + Assertions.assertTrue(errorsList.size > 0) val error = errorsList[0].error @@ -247,12 +244,12 @@ class DataBrokerConnectionTest : BehaviorSpec({ val response = dataBrokerConnection.fetch(property) then("The response should not contain any entries") { - assertEquals(0, response.entriesList.size) + Assertions.assertEquals(0, response.entriesList.size) } then("The response should contain an error with errorCode 404 (path not found)") { val errorsList = response.errorsList - assertTrue(errorsList.size > 0) + Assertions.assertTrue(errorsList.size > 0) val error = errorsList[0].error @@ -292,16 +289,16 @@ class DataBrokerConnectionTest : BehaviorSpec({ } }) -private fun createRandomFloatDatapoint(): Datapoint { +private fun createRandomFloatDatapoint(): Types.Datapoint { val random = Random(System.currentTimeMillis()) val newValue = random.nextFloat() - return Datapoint.newBuilder().setFloat(newValue).build() + return Types.Datapoint.newBuilder().setFloat(newValue).build() } -private fun createRandomIntDatapoint(): Datapoint { +private fun createRandomIntDatapoint(): Types.Datapoint { val random = Random(System.currentTimeMillis()) val newValue = random.nextInt() - return Datapoint.newBuilder().setInt32(newValue).build() + return Types.Datapoint.newBuilder().setInt32(newValue).build() } private fun connectToDataBrokerBlocking(): DataBrokerConnection { diff --git a/kuksa-sdk/src/test/kotlin/org/eclipse/kuksa/databroker/DataBrokerConnectorProvider.kt b/kuksa-sdk/src/test/kotlin/org/eclipse/kuksa/connectivity/databroker/DataBrokerConnectorProvider.kt similarity index 94% rename from kuksa-sdk/src/test/kotlin/org/eclipse/kuksa/databroker/DataBrokerConnectorProvider.kt rename to kuksa-sdk/src/test/kotlin/org/eclipse/kuksa/connectivity/databroker/DataBrokerConnectorProvider.kt index 327833bb..0e5cec2b 100644 --- a/kuksa-sdk/src/test/kotlin/org/eclipse/kuksa/databroker/DataBrokerConnectorProvider.kt +++ b/kuksa-sdk/src/test/kotlin/org/eclipse/kuksa/connectivity/databroker/DataBrokerConnectorProvider.kt @@ -14,19 +14,17 @@ * limitations under the License. * * SPDX-License-Identifier: Apache-2.0 - * */ -package org.eclipse.kuksa.databroker +package org.eclipse.kuksa.connectivity.databroker import io.grpc.ChannelCredentials import io.grpc.Grpc import io.grpc.ManagedChannel import io.grpc.ManagedChannelBuilder import io.grpc.TlsChannelCredentials -import org.eclipse.kuksa.DataBrokerConnector -import org.eclipse.kuksa.TimeoutConfig -import org.eclipse.kuksa.authentication.JsonWebToken +import org.eclipse.kuksa.model.TimeoutConfig +import org.eclipse.kuksa.connectivity.authentication.JsonWebToken import java.io.IOException import java.io.InputStream diff --git a/kuksa-sdk/src/test/kotlin/org/eclipse/kuksa/DataBrokerConnectorSecureTest.kt b/kuksa-sdk/src/test/kotlin/org/eclipse/kuksa/connectivity/databroker/DataBrokerConnectorSecureTest.kt similarity index 88% rename from kuksa-sdk/src/test/kotlin/org/eclipse/kuksa/DataBrokerConnectorSecureTest.kt rename to kuksa-sdk/src/test/kotlin/org/eclipse/kuksa/connectivity/databroker/DataBrokerConnectorSecureTest.kt index db185bca..d8aa8064 100644 --- a/kuksa-sdk/src/test/kotlin/org/eclipse/kuksa/DataBrokerConnectorSecureTest.kt +++ b/kuksa-sdk/src/test/kotlin/org/eclipse/kuksa/connectivity/databroker/DataBrokerConnectorSecureTest.kt @@ -14,21 +14,16 @@ * limitations under the License. * * SPDX-License-Identifier: Apache-2.0 - * */ -package org.eclipse.kuksa +package org.eclipse.kuksa.connectivity.databroker import io.kotest.core.spec.style.BehaviorSpec -import org.eclipse.kuksa.databroker.DataBrokerConnectorProvider import org.eclipse.kuksa.test.kotest.CustomDatabroker import org.eclipse.kuksa.test.kotest.Integration import org.eclipse.kuksa.test.kotest.Secure import org.junit.jupiter.api.Assertions -// DataBroker must be started with TLS enabled: -// databroker --tls-cert /certs/Server.pem --tls-private-key /certs/Server.key" - // run command: ./gradlew clean test -Dkotest.tags="Secure" class DataBrokerConnectorSecureTest : BehaviorSpec({ tags(Integration, Secure, CustomDatabroker) diff --git a/kuksa-sdk/src/test/kotlin/org/eclipse/kuksa/DataBrokerConnectorTest.kt b/kuksa-sdk/src/test/kotlin/org/eclipse/kuksa/connectivity/databroker/DataBrokerConnectorTest.kt similarity index 95% rename from kuksa-sdk/src/test/kotlin/org/eclipse/kuksa/DataBrokerConnectorTest.kt rename to kuksa-sdk/src/test/kotlin/org/eclipse/kuksa/connectivity/databroker/DataBrokerConnectorTest.kt index b825a5d4..63e30827 100644 --- a/kuksa-sdk/src/test/kotlin/org/eclipse/kuksa/DataBrokerConnectorTest.kt +++ b/kuksa-sdk/src/test/kotlin/org/eclipse/kuksa/connectivity/databroker/DataBrokerConnectorTest.kt @@ -14,15 +14,13 @@ * limitations under the License. * * SPDX-License-Identifier: Apache-2.0 - * */ -package org.eclipse.kuksa +package org.eclipse.kuksa.connectivity.databroker import io.kotest.assertions.throwables.shouldThrow import io.kotest.core.spec.style.BehaviorSpec import io.kotest.matchers.shouldNotBe -import org.eclipse.kuksa.databroker.DataBrokerConnectorProvider import org.eclipse.kuksa.test.kotest.DefaultDatabroker import org.eclipse.kuksa.test.kotest.Insecure import org.eclipse.kuksa.test.kotest.Integration diff --git a/kuksa-sdk/src/test/kotlin/org/eclipse/kuksa/DataBrokerTransporterTest.kt b/kuksa-sdk/src/test/kotlin/org/eclipse/kuksa/connectivity/databroker/DataBrokerTransporterTest.kt similarity index 94% rename from kuksa-sdk/src/test/kotlin/org/eclipse/kuksa/DataBrokerTransporterTest.kt rename to kuksa-sdk/src/test/kotlin/org/eclipse/kuksa/connectivity/databroker/DataBrokerTransporterTest.kt index fc3200f7..b3b74028 100644 --- a/kuksa-sdk/src/test/kotlin/org/eclipse/kuksa/DataBrokerTransporterTest.kt +++ b/kuksa-sdk/src/test/kotlin/org/eclipse/kuksa/connectivity/databroker/DataBrokerTransporterTest.kt @@ -14,10 +14,9 @@ * limitations under the License. * * SPDX-License-Identifier: Apache-2.0 - * */ -package org.eclipse.kuksa +package org.eclipse.kuksa.connectivity.databroker import io.grpc.ManagedChannelBuilder import io.kotest.core.spec.style.BehaviorSpec @@ -26,12 +25,10 @@ import io.kotest.matchers.shouldNotBe import io.kotest.matchers.types.instanceOf import io.mockk.mockk import io.mockk.verify -import org.eclipse.kuksa.databroker.DataBrokerConnectorProvider +import org.eclipse.kuksa.connectivity.databroker.listener.PropertyListener import org.eclipse.kuksa.extensions.updateRandomFloatValue import org.eclipse.kuksa.proto.v1.KuksaValV1 -import org.eclipse.kuksa.proto.v1.KuksaValV1.SetResponse import org.eclipse.kuksa.proto.v1.Types -import org.eclipse.kuksa.proto.v1.Types.Datapoint import org.eclipse.kuksa.test.kotest.DefaultDatabroker import org.eclipse.kuksa.test.kotest.Insecure import org.eclipse.kuksa.test.kotest.Integration @@ -55,7 +52,7 @@ class DataBrokerTransporterTest : BehaviorSpec({ val valueToSet = random.nextInt(250).toFloat() `when`("Updating the $fields of $vssPath to $valueToSet km/h") { - val updatedDatapoint = Datapoint.newBuilder().setFloat(valueToSet).build() + val updatedDatapoint = Types.Datapoint.newBuilder().setFloat(valueToSet).build() val result = kotlin.runCatching { classUnderTest.update(vssPath, fields, updatedDatapoint) } @@ -67,7 +64,7 @@ class DataBrokerTransporterTest : BehaviorSpec({ then("It should return a valid SetResponse") { val response = result.getOrNull() response shouldNotBe null - response shouldBe instanceOf(SetResponse::class) + response shouldBe instanceOf(KuksaValV1.SetResponse::class) } } diff --git a/kuksa-sdk/src/test/kotlin/org/eclipse/kuksa/subscription/DataBrokerSubscriberTest.kt b/kuksa-sdk/src/test/kotlin/org/eclipse/kuksa/connectivity/databroker/subscription/DataBrokerSubscriberTest.kt similarity index 97% rename from kuksa-sdk/src/test/kotlin/org/eclipse/kuksa/subscription/DataBrokerSubscriberTest.kt rename to kuksa-sdk/src/test/kotlin/org/eclipse/kuksa/connectivity/databroker/subscription/DataBrokerSubscriberTest.kt index 7dad622e..006eb5a0 100644 --- a/kuksa-sdk/src/test/kotlin/org/eclipse/kuksa/subscription/DataBrokerSubscriberTest.kt +++ b/kuksa-sdk/src/test/kotlin/org/eclipse/kuksa/connectivity/databroker/subscription/DataBrokerSubscriberTest.kt @@ -14,10 +14,9 @@ * limitations under the License. * * SPDX-License-Identifier: Apache-2.0 - * */ -package org.eclipse.kuksa.subscription +package org.eclipse.kuksa.connectivity.databroker.subscription import io.kotest.assertions.nondeterministic.continually import io.kotest.assertions.nondeterministic.eventually @@ -28,9 +27,9 @@ import io.mockk.every import io.mockk.mockk import io.mockk.verify import kotlinx.coroutines.delay -import org.eclipse.kuksa.DataBrokerTransporter -import org.eclipse.kuksa.PropertyListener -import org.eclipse.kuksa.databroker.DataBrokerConnectorProvider +import org.eclipse.kuksa.connectivity.databroker.DataBrokerTransporter +import org.eclipse.kuksa.connectivity.databroker.listener.PropertyListener +import org.eclipse.kuksa.connectivity.databroker.DataBrokerConnectorProvider import org.eclipse.kuksa.extensions.toggleBoolean import org.eclipse.kuksa.extensions.updateRandomFloatValue import org.eclipse.kuksa.extensions.updateRandomUint32Value @@ -285,7 +284,7 @@ class DataBrokerSubscriberTest : BehaviorSpec({ } given("An Instance of DataBrokerSubscriber with a mocked DataBrokerTransporter") { - val subscriptionMock = mockk(relaxed = true) + val subscriptionMock = mockk(relaxed = true) val dataBrokerTransporterMock = mockk(relaxed = true) val multiListener = MultiListener() every { dataBrokerTransporterMock.subscribe(any(), any()) } returns subscriptionMock diff --git a/kuksa-sdk/src/test/kotlin/org/eclipse/kuksa/extensions/DataBrokerTransporterExtensions.kt b/kuksa-sdk/src/test/kotlin/org/eclipse/kuksa/extensions/DataBrokerTransporterExtensions.kt index 8fc91105..acd132e3 100644 --- a/kuksa-sdk/src/test/kotlin/org/eclipse/kuksa/extensions/DataBrokerTransporterExtensions.kt +++ b/kuksa-sdk/src/test/kotlin/org/eclipse/kuksa/extensions/DataBrokerTransporterExtensions.kt @@ -20,7 +20,7 @@ package org.eclipse.kuksa.extensions import io.kotest.assertions.fail -import org.eclipse.kuksa.DataBrokerTransporter +import org.eclipse.kuksa.connectivity.databroker.DataBrokerTransporter import org.eclipse.kuksa.proto.v1.Types import kotlin.random.Random diff --git a/kuksa-sdk/src/test/kotlin/org/eclipse/kuksa/mocking/FriendlyPropertyListener.kt b/kuksa-sdk/src/test/kotlin/org/eclipse/kuksa/mocking/FriendlyPropertyListener.kt index 514f1f5b..026653d1 100644 --- a/kuksa-sdk/src/test/kotlin/org/eclipse/kuksa/mocking/FriendlyPropertyListener.kt +++ b/kuksa-sdk/src/test/kotlin/org/eclipse/kuksa/mocking/FriendlyPropertyListener.kt @@ -19,7 +19,7 @@ package org.eclipse.kuksa.mocking -import org.eclipse.kuksa.PropertyListener +import org.eclipse.kuksa.connectivity.databroker.listener.PropertyListener import org.eclipse.kuksa.proto.v1.KuksaValV1 class FriendlyPropertyListener : PropertyListener { diff --git a/kuksa-sdk/src/test/kotlin/org/eclipse/kuksa/mocking/FriendlyVssNodeListener.kt b/kuksa-sdk/src/test/kotlin/org/eclipse/kuksa/mocking/FriendlyVssNodeListener.kt index f1a4fe52..66c88b19 100644 --- a/kuksa-sdk/src/test/kotlin/org/eclipse/kuksa/mocking/FriendlyVssNodeListener.kt +++ b/kuksa-sdk/src/test/kotlin/org/eclipse/kuksa/mocking/FriendlyVssNodeListener.kt @@ -19,7 +19,7 @@ package org.eclipse.kuksa.mocking -import org.eclipse.kuksa.VssNodeListener +import org.eclipse.kuksa.connectivity.databroker.listener.VssNodeListener import org.eclipse.kuksa.vsscore.model.VssNode class FriendlyVssNodeListener : VssNodeListener { diff --git a/samples/src/main/java/com/example/sample/JavaActivity.java b/samples/src/main/java/com/example/sample/JavaActivity.java index d2bded31..67b0133b 100644 --- a/samples/src/main/java/com/example/sample/JavaActivity.java +++ b/samples/src/main/java/com/example/sample/JavaActivity.java @@ -22,13 +22,13 @@ import androidx.annotation.NonNull; import androidx.appcompat.app.AppCompatActivity; -import org.eclipse.kuksa.CoroutineCallback; -import org.eclipse.kuksa.DataBrokerConnection; -import org.eclipse.kuksa.DataBrokerConnector; -import org.eclipse.kuksa.DisconnectListener; -import org.eclipse.kuksa.PropertyListener; -import org.eclipse.kuksa.VssNodeListener; -import org.eclipse.kuksa.authentication.JsonWebToken; +import org.eclipse.kuksa.coroutine.CoroutineCallback; +import org.eclipse.kuksa.connectivity.databroker.DataBrokerConnection; +import org.eclipse.kuksa.connectivity.databroker.DataBrokerConnector; +import org.eclipse.kuksa.connectivity.databroker.listener.DisconnectListener; +import org.eclipse.kuksa.connectivity.databroker.listener.PropertyListener; +import org.eclipse.kuksa.connectivity.databroker.listener.VssNodeListener; +import org.eclipse.kuksa.connectivity.authentication.JsonWebToken; import org.eclipse.kuksa.model.Property; import org.eclipse.kuksa.proto.v1.KuksaValV1; import org.eclipse.kuksa.proto.v1.KuksaValV1.GetResponse; diff --git a/samples/src/main/kotlin/com/example/sample/KotlinActivity.kt b/samples/src/main/kotlin/com/example/sample/KotlinActivity.kt index c21c1f7f..f1131378 100644 --- a/samples/src/main/kotlin/com/example/sample/KotlinActivity.kt +++ b/samples/src/main/kotlin/com/example/sample/KotlinActivity.kt @@ -26,13 +26,13 @@ import io.grpc.Grpc import io.grpc.ManagedChannelBuilder import io.grpc.TlsChannelCredentials import kotlinx.coroutines.launch -import org.eclipse.kuksa.DataBrokerConnection -import org.eclipse.kuksa.DataBrokerConnector -import org.eclipse.kuksa.DataBrokerException -import org.eclipse.kuksa.DisconnectListener -import org.eclipse.kuksa.PropertyListener -import org.eclipse.kuksa.VssNodeListener -import org.eclipse.kuksa.authentication.JsonWebToken +import org.eclipse.kuksa.connectivity.databroker.DataBrokerConnection +import org.eclipse.kuksa.connectivity.databroker.DataBrokerConnector +import org.eclipse.kuksa.connectivity.databroker.DataBrokerException +import org.eclipse.kuksa.connectivity.databroker.listener.DisconnectListener +import org.eclipse.kuksa.connectivity.databroker.listener.PropertyListener +import org.eclipse.kuksa.connectivity.databroker.listener.VssNodeListener +import org.eclipse.kuksa.connectivity.authentication.JsonWebToken import org.eclipse.kuksa.model.Property import org.eclipse.kuksa.proto.v1.KuksaValV1 import org.eclipse.kuksa.proto.v1.Types From 8335f51040d3d487d366ee760ab87fab9e7bf0a9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mark=20Hu=CC=88sers?= Date: Fri, 1 Mar 2024 16:29:01 +0100 Subject: [PATCH 08/20] chore: Correct missed naming --- .../databroker/JavaDataBrokerEngine.java | 16 ++++----- .../kuksa/testapp/KuksaDataBrokerActivity.kt | 30 ++++++++-------- .../testapp/databroker/DataBrokerEngine.kt | 12 +++---- .../databroker/KotlinDataBrokerEngine.kt | 18 +++++----- .../connection/DataBrokerConnectorFactory.kt | 2 +- .../testapp/databroker/view/DataBrokerView.kt | 31 ++++++++-------- .../viewmodel/TopAppBarViewModel.kt | 10 +++--- .../databroker/viewmodel/VssViewModel.kt | 18 +++++----- docs/QUICKSTART.md | 14 ++++---- .../databroker/DataBrokerConnection.kt | 12 +++---- .../databroker/DataBrokerConnector.kt | 3 +- .../databroker/DataBrokerTransporter.kt | 6 ++-- .../subscription/DataBrokerSubscriber.kt | 35 +++++++++--------- .../SpecificationPropertyListener.kt | 2 +- .../extension/VssSpecificationExtension.kt | 4 +-- .../VssLeafBooleanExtension.kt} | 3 +- .../VssLeafDoubleExtension.kt} | 3 +- .../VssLeafFloatExtension.kt} | 3 +- .../VssLeafIntExtension.kt} | 3 +- .../VssLeafLongExtension.kt} | 3 +- .../VssNodeCopyExtension.kt} | 20 +++++------ .../org/eclipse/kuksa/model/Property.kt | 2 +- .../databroker/DataBrokerConnectorProvider.kt | 2 +- .../kuksa/vssNode/VssNodeArithmeticTest.kt | 8 ++--- .../eclipse/kuksa/vssNode/VssNodeCopyTest.kt | 8 ++--- .../java/com/example/sample/JavaActivity.java | 6 ++-- .../com/example/sample/KotlinActivity.kt | 12 +++---- .../vsscore/annotation/VssModelGenerator.kt | 0 .../vsscore/extension/StringExtension.kt | 0 .../eclipse/kuksa/vsscore/model/VssNode.kt | 2 +- .../vssprocessor/plugin/VssProcessorPlugin.kt | 2 +- .../vssprocessor/spec/VssNodeSpecModel.kt | 4 +-- ...tionParserTest.kt => YamlVssParserTest.kt} | 36 +++++++++++-------- 33 files changed, 165 insertions(+), 165 deletions(-) rename kuksa-sdk/src/main/kotlin/org/eclipse/kuksa/extension/{vssProperty/VssPropertyBooleanExtension.kt => vss/VssLeafBooleanExtension.kt} (92%) rename kuksa-sdk/src/main/kotlin/org/eclipse/kuksa/extension/{vssProperty/VssPropertyDoubleExtension.kt => vss/VssLeafDoubleExtension.kt} (97%) rename kuksa-sdk/src/main/kotlin/org/eclipse/kuksa/extension/{vssProperty/VssPropertyFloatExtension.kt => vss/VssLeafFloatExtension.kt} (97%) rename kuksa-sdk/src/main/kotlin/org/eclipse/kuksa/extension/{vssProperty/VssPropertyIntExtension.kt => vss/VssLeafIntExtension.kt} (97%) rename kuksa-sdk/src/main/kotlin/org/eclipse/kuksa/extension/{vssProperty/VssPropertyLongExtension.kt => vss/VssLeafLongExtension.kt} (97%) rename kuksa-sdk/src/main/kotlin/org/eclipse/kuksa/extension/{VssSpecificationCopyExtension.kt => vss/VssNodeCopyExtension.kt} (93%) rename vss-core/src/main/{java => kotlin}/org/eclipse/kuksa/vsscore/annotation/VssModelGenerator.kt (100%) rename vss-core/src/main/{java => kotlin}/org/eclipse/kuksa/vsscore/extension/StringExtension.kt (100%) rename vss-core/src/main/{java => kotlin}/org/eclipse/kuksa/vsscore/model/VssNode.kt (99%) rename vss-processor/src/test/kotlin/org/eclipse/kuksa/vssprocessor/parser/{YamlDefinitionParserTest.kt => YamlVssParserTest.kt} (60%) diff --git a/app/src/main/java/org/eclipse/kuksa/testapp/databroker/JavaDataBrokerEngine.java b/app/src/main/java/org/eclipse/kuksa/testapp/databroker/JavaDataBrokerEngine.java index 3702ecce..cee2dbed 100644 --- a/app/src/main/java/org/eclipse/kuksa/testapp/databroker/JavaDataBrokerEngine.java +++ b/app/src/main/java/org/eclipse/kuksa/testapp/databroker/JavaDataBrokerEngine.java @@ -101,14 +101,14 @@ public void fetch(@NonNull Property property, @NonNull CoroutineCallback void fetch( - @NonNull T specification, + @NonNull T vssNode, @NonNull CoroutineCallback callback ) { if (dataBrokerConnection == null) { return; } - dataBrokerConnection.fetch(specification, callback); + dataBrokerConnection.fetch(vssNode, callback); } @Override @@ -135,8 +135,8 @@ public void subscribe(@NonNull Property property, @NonNull PropertyListener prop @Override public void subscribe( - @NonNull T specification, - @NonNull VssNodeListener specificationListener + @NonNull T vssNode, + @NonNull VssNodeListener vssNodeListener ) { if (dataBrokerConnection == null) { return; @@ -148,13 +148,13 @@ public void subscribe( } }; - dataBrokerConnection.subscribe(specification, fields, specificationListener); + dataBrokerConnection.subscribe(vssNode, fields, vssNodeListener); } @Override public void unsubscribe( - @NonNull T specification, - @NonNull VssNodeListener specificationListener + @NonNull T vssNode, + @NonNull VssNodeListener vssNodeListener ) { if (dataBrokerConnection == null) { return; @@ -166,7 +166,7 @@ public void unsubscribe( } }; - dataBrokerConnection.unsubscribe(specification, fields, specificationListener); + dataBrokerConnection.unsubscribe(vssNode, fields, vssNodeListener); } public void disconnect() { diff --git a/app/src/main/kotlin/org/eclipse/kuksa/testapp/KuksaDataBrokerActivity.kt b/app/src/main/kotlin/org/eclipse/kuksa/testapp/KuksaDataBrokerActivity.kt index 5b617530..ac222c21 100644 --- a/app/src/main/kotlin/org/eclipse/kuksa/testapp/KuksaDataBrokerActivity.kt +++ b/app/src/main/kotlin/org/eclipse/kuksa/testapp/KuksaDataBrokerActivity.kt @@ -29,11 +29,11 @@ import androidx.compose.material3.MaterialTheme import androidx.compose.material3.Surface import androidx.compose.ui.Modifier import androidx.lifecycle.lifecycleScope -import org.eclipse.kuksa.coroutine.CoroutineCallback import org.eclipse.kuksa.connectivity.databroker.DataBrokerConnection import org.eclipse.kuksa.connectivity.databroker.listener.DisconnectListener import org.eclipse.kuksa.connectivity.databroker.listener.PropertyListener import org.eclipse.kuksa.connectivity.databroker.listener.VssNodeListener +import org.eclipse.kuksa.coroutine.CoroutineCallback import org.eclipse.kuksa.extension.entriesMetadata import org.eclipse.kuksa.extension.valueType import org.eclipse.kuksa.model.Property @@ -108,13 +108,13 @@ class KuksaDataBrokerActivity : ComponentActivity() { } } - private val specificationListener = object : VssNodeListener { + private val vssNodeListener = object : VssNodeListener { override fun onNodeChanged(vssNode: VssNode) { - outputViewModel.addOutputEntry("Updated specification: $vssNode") + outputViewModel.addOutputEntry("Updated node: $vssNode") } override fun onError(throwable: Throwable) { - outputViewModel.addOutputEntry("Updated specification: ${throwable.message}") + outputViewModel.addOutputEntry("Updated node: ${throwable.message}") } } @@ -186,16 +186,16 @@ class KuksaDataBrokerActivity : ComponentActivity() { dataBrokerEngine.unsubscribe(property, propertyListener) } - vssViewModel.onSubscribeSpecification = { specification -> - dataBrokerEngine.subscribe(specification, specificationListener) + vssViewModel.onSubscribeNode = { vssNode -> + dataBrokerEngine.subscribe(vssNode, vssNodeListener) } - vssViewModel.onUnsubscribeSpecification = { specification -> - dataBrokerEngine.unsubscribe(specification, specificationListener) + vssViewModel.onUnsubscribeNode = { vssNode -> + dataBrokerEngine.unsubscribe(vssNode, vssNodeListener) } - vssViewModel.onGetSpecification = { specification -> - fetchSpecification(specification) + vssViewModel.onGetNode = { vssNode -> + fetchVssNode(vssNode) } } @@ -304,17 +304,17 @@ class KuksaDataBrokerActivity : ComponentActivity() { ) } - private fun fetchSpecification(specification: VssNode) { + private fun fetchVssNode(vssNode: VssNode) { dataBrokerEngine.fetch( - specification, + vssNode, object : CoroutineCallback() { override fun onSuccess(result: VssNode?) { - Log.d(TAG, "Fetched specification: $result") - outputViewModel.addOutputEntry("Fetched specification: $result") + Log.d(TAG, "Fetched node: $result") + outputViewModel.addOutputEntry("Fetched node: $result") } override fun onError(error: Throwable) { - outputViewModel.addOutputEntry("Could not fetch specification: ${error.message}") + outputViewModel.addOutputEntry("Could not fetch node: ${error.message}") } }, ) diff --git a/app/src/main/kotlin/org/eclipse/kuksa/testapp/databroker/DataBrokerEngine.kt b/app/src/main/kotlin/org/eclipse/kuksa/testapp/databroker/DataBrokerEngine.kt index 2116dfa6..414fe752 100644 --- a/app/src/main/kotlin/org/eclipse/kuksa/testapp/databroker/DataBrokerEngine.kt +++ b/app/src/main/kotlin/org/eclipse/kuksa/testapp/databroker/DataBrokerEngine.kt @@ -20,11 +20,11 @@ package org.eclipse.kuksa.testapp.databroker import android.content.Context -import org.eclipse.kuksa.coroutine.CoroutineCallback import org.eclipse.kuksa.connectivity.databroker.DataBrokerConnection import org.eclipse.kuksa.connectivity.databroker.listener.DisconnectListener import org.eclipse.kuksa.connectivity.databroker.listener.PropertyListener import org.eclipse.kuksa.connectivity.databroker.listener.VssNodeListener +import org.eclipse.kuksa.coroutine.CoroutineCallback import org.eclipse.kuksa.model.Property import org.eclipse.kuksa.proto.v1.KuksaValV1.GetResponse import org.eclipse.kuksa.proto.v1.KuksaValV1.SetResponse @@ -47,7 +47,7 @@ interface DataBrokerEngine { callback: CoroutineCallback, ) - fun fetch(specification: T, callback: CoroutineCallback) + fun fetch(vssNode: T, callback: CoroutineCallback) fun update( property: Property, @@ -60,13 +60,13 @@ interface DataBrokerEngine { fun unsubscribe(property: Property, propertyListener: PropertyListener) fun subscribe( - specification: T, - specificationListener: VssNodeListener, + vssNode: T, + vssNodeListener: VssNodeListener, ) fun unsubscribe( - specification: T, - specificationListener: VssNodeListener, + vssNode: T, + vssNodeListener: VssNodeListener, ) fun disconnect() diff --git a/app/src/main/kotlin/org/eclipse/kuksa/testapp/databroker/KotlinDataBrokerEngine.kt b/app/src/main/kotlin/org/eclipse/kuksa/testapp/databroker/KotlinDataBrokerEngine.kt index 85097f86..f6f6ef5c 100644 --- a/app/src/main/kotlin/org/eclipse/kuksa/testapp/databroker/KotlinDataBrokerEngine.kt +++ b/app/src/main/kotlin/org/eclipse/kuksa/testapp/databroker/KotlinDataBrokerEngine.kt @@ -22,13 +22,13 @@ package org.eclipse.kuksa.testapp.databroker import android.content.Context import androidx.lifecycle.LifecycleCoroutineScope import kotlinx.coroutines.launch -import org.eclipse.kuksa.coroutine.CoroutineCallback import org.eclipse.kuksa.connectivity.databroker.DataBrokerConnection import org.eclipse.kuksa.connectivity.databroker.DataBrokerConnector import org.eclipse.kuksa.connectivity.databroker.DataBrokerException import org.eclipse.kuksa.connectivity.databroker.listener.DisconnectListener import org.eclipse.kuksa.connectivity.databroker.listener.PropertyListener import org.eclipse.kuksa.connectivity.databroker.listener.VssNodeListener +import org.eclipse.kuksa.coroutine.CoroutineCallback import org.eclipse.kuksa.model.Property import org.eclipse.kuksa.proto.v1.KuksaValV1.GetResponse import org.eclipse.kuksa.proto.v1.KuksaValV1.SetResponse @@ -85,10 +85,10 @@ class KotlinDataBrokerEngine( } } - override fun fetch(specification: T, callback: CoroutineCallback) { + override fun fetch(vssNode: T, callback: CoroutineCallback) { lifecycleScope.launch { try { - val response = dataBrokerConnection?.fetch(specification) ?: return@launch + val response = dataBrokerConnection?.fetch(vssNode) ?: return@launch callback.onSuccess(response) } catch (e: DataBrokerException) { callback.onError(e) @@ -116,19 +116,19 @@ class KotlinDataBrokerEngine( } override fun subscribe( - specification: T, - specificationListener: VssNodeListener, + vssNode: T, + vssNodeListener: VssNodeListener, ) { lifecycleScope.launch { - dataBrokerConnection?.subscribe(specification, listener = specificationListener) + dataBrokerConnection?.subscribe(vssNode, listener = vssNodeListener) } } override fun unsubscribe( - specification: T, - specificationListener: VssNodeListener, + vssNode: T, + vssNodeListener: VssNodeListener, ) { - dataBrokerConnection?.unsubscribe(specification, listener = specificationListener) + dataBrokerConnection?.unsubscribe(vssNode, listener = vssNodeListener) } override fun disconnect() { diff --git a/app/src/main/kotlin/org/eclipse/kuksa/testapp/databroker/connection/DataBrokerConnectorFactory.kt b/app/src/main/kotlin/org/eclipse/kuksa/testapp/databroker/connection/DataBrokerConnectorFactory.kt index 895b6e1a..02ceb3a1 100644 --- a/app/src/main/kotlin/org/eclipse/kuksa/testapp/databroker/connection/DataBrokerConnectorFactory.kt +++ b/app/src/main/kotlin/org/eclipse/kuksa/testapp/databroker/connection/DataBrokerConnectorFactory.kt @@ -26,9 +26,9 @@ import io.grpc.Grpc import io.grpc.ManagedChannel import io.grpc.ManagedChannelBuilder import io.grpc.TlsChannelCredentials +import org.eclipse.kuksa.connectivity.authentication.JsonWebToken import org.eclipse.kuksa.connectivity.databroker.DataBrokerConnector import org.eclipse.kuksa.model.TimeoutConfig -import org.eclipse.kuksa.connectivity.authentication.JsonWebToken import org.eclipse.kuksa.testapp.databroker.model.ConnectionInfo import org.eclipse.kuksa.testapp.extension.readAsText import java.io.IOException diff --git a/app/src/main/kotlin/org/eclipse/kuksa/testapp/databroker/view/DataBrokerView.kt b/app/src/main/kotlin/org/eclipse/kuksa/testapp/databroker/view/DataBrokerView.kt index fc9060f5..c4799115 100644 --- a/app/src/main/kotlin/org/eclipse/kuksa/testapp/databroker/view/DataBrokerView.kt +++ b/app/src/main/kotlin/org/eclipse/kuksa/testapp/databroker/view/DataBrokerView.kt @@ -23,7 +23,6 @@ import androidx.compose.foundation.clickable import androidx.compose.foundation.layout.Arrangement import androidx.compose.foundation.layout.Box import androidx.compose.foundation.layout.Column -import androidx.compose.foundation.layout.ExperimentalLayoutApi import androidx.compose.foundation.layout.Row import androidx.compose.foundation.layout.Spacer import androidx.compose.foundation.layout.consumeWindowInsets @@ -127,7 +126,7 @@ fun DataBrokerView( if (connectionViewModel.isConnected) { when (dataBrokerMode) { DataBrokerMode.VSS_PATH -> DataBrokerProperties(vssPropertiesViewModel) - DataBrokerMode.SPECIFICATION -> DataBrokerSpecifications(vssViewModel) + DataBrokerMode.VSS_FILE -> DataBrokerVssNodes(vssViewModel) } } Spacer(modifier = Modifier.padding(top = DefaultElementPadding)) @@ -187,8 +186,8 @@ private fun SettingsMenu( Row( modifier = Modifier .clickable { - val newMode = if (!topAppBarViewModel.isSpecificationModeEnabled) { - DataBrokerMode.SPECIFICATION + val newMode = if (!topAppBarViewModel.isVssFileModeEnabled) { + DataBrokerMode.VSS_FILE } else { DataBrokerMode.VSS_PATH } @@ -197,10 +196,10 @@ private fun SettingsMenu( .padding(horizontal = SettingsMenuPadding), ) { Checkbox( - checked = topAppBarViewModel.isSpecificationModeEnabled, + checked = topAppBarViewModel.isVssFileModeEnabled, onCheckedChange = null, ) - Text(text = "Specification Mode", modifier = Modifier.padding(start = SettingsMenuPadding)) + Text(text = "VSS Mode", modifier = Modifier.padding(start = SettingsMenuPadding)) } } } @@ -234,9 +233,9 @@ private fun ConnectionStatusIcon( } @Composable -fun DataBrokerSpecifications(viewModel: VssViewModel) { +fun DataBrokerVssNodes(viewModel: VssViewModel) { Column { - Headline(name = "Specifications") + Headline(name = "VSS Nodes") val adapter = object : SuggestionAdapter { override fun toString(item: VssNode): String { @@ -246,11 +245,11 @@ fun DataBrokerSpecifications(viewModel: VssViewModel) { SuggestionTextView( value = "Vehicle", - suggestions = viewModel.specifications, + suggestions = viewModel.vssNodes, adapter = adapter, onItemSelected = { - val specification = it ?: VssVehicle() - viewModel.updateSpecification(specification) + val vssNode = it ?: VssVehicle() + viewModel.updateNode(vssNode) }, modifier = Modifier .fillMaxWidth() @@ -263,7 +262,7 @@ fun DataBrokerSpecifications(viewModel: VssViewModel) { ) { Button( onClick = { - viewModel.onGetSpecification(viewModel.specification) + viewModel.onGetNode(viewModel.node) }, modifier = Modifier.requiredWidth(80.dp), ) { @@ -271,15 +270,15 @@ fun DataBrokerSpecifications(viewModel: VssViewModel) { } if (viewModel.isSubscribed) { Button(onClick = { - viewModel.subscribedSpecifications.remove(viewModel.specification) - viewModel.onUnsubscribeSpecification(viewModel.specification) + viewModel.subscribedNodes.remove(viewModel.node) + viewModel.onUnsubscribeNode(viewModel.node) }) { Text(text = "Unsubscribe") } } else { Button(onClick = { - viewModel.subscribedSpecifications.add(viewModel.specification) - viewModel.onSubscribeSpecification(viewModel.specification) + viewModel.subscribedNodes.add(viewModel.node) + viewModel.onSubscribeNode(viewModel.node) }) { Text(text = "Subscribe") } diff --git a/app/src/main/kotlin/org/eclipse/kuksa/testapp/databroker/viewmodel/TopAppBarViewModel.kt b/app/src/main/kotlin/org/eclipse/kuksa/testapp/databroker/viewmodel/TopAppBarViewModel.kt index 86bb7329..5c56d0c5 100644 --- a/app/src/main/kotlin/org/eclipse/kuksa/testapp/databroker/viewmodel/TopAppBarViewModel.kt +++ b/app/src/main/kotlin/org/eclipse/kuksa/testapp/databroker/viewmodel/TopAppBarViewModel.kt @@ -31,11 +31,11 @@ import kotlinx.coroutines.flow.onEach class TopAppBarViewModel : ViewModel() { enum class DataBrokerMode { VSS_PATH, - SPECIFICATION, + VSS_FILE, } var isCompatibilityModeEnabled by mutableStateOf(false) - var isSpecificationModeEnabled by mutableStateOf(false) + var isVssFileModeEnabled by mutableStateOf(false) private set var onCompatibilityModeChanged: ((Boolean) -> Unit)? = null @@ -49,16 +49,16 @@ class TopAppBarViewModel : ViewModel() { .onEach { onCompatibilityModeChanged?.invoke(it) } .launchIn(viewModelScope) - snapshotFlow { isSpecificationModeEnabled } + snapshotFlow { isVssFileModeEnabled } .onEach { - val mode = if (isSpecificationModeEnabled) DataBrokerMode.SPECIFICATION else DataBrokerMode.VSS_PATH + val mode = if (isVssFileModeEnabled) DataBrokerMode.VSS_FILE else DataBrokerMode.VSS_PATH onDataBrokerModeChanged?.invoke(mode) } .launchIn(viewModelScope) snapshotFlow { dataBrokerMode } .onEach { - isSpecificationModeEnabled = it == DataBrokerMode.SPECIFICATION + isVssFileModeEnabled = it == DataBrokerMode.VSS_FILE } .launchIn(viewModelScope) } diff --git a/app/src/main/kotlin/org/eclipse/kuksa/testapp/databroker/viewmodel/VssViewModel.kt b/app/src/main/kotlin/org/eclipse/kuksa/testapp/databroker/viewmodel/VssViewModel.kt index d96d7202..121bea0f 100644 --- a/app/src/main/kotlin/org/eclipse/kuksa/testapp/databroker/viewmodel/VssViewModel.kt +++ b/app/src/main/kotlin/org/eclipse/kuksa/testapp/databroker/viewmodel/VssViewModel.kt @@ -30,23 +30,23 @@ import org.eclipse.kuksa.vsscore.model.VssNode import org.eclipse.kuksa.vsscore.model.heritage class VssViewModel : ViewModel() { - var onGetSpecification: (specification: VssNode) -> Unit = { } - var onSubscribeSpecification: (specification: VssNode) -> Unit = { } - var onUnsubscribeSpecification: (specification: VssNode) -> Unit = { } + var onGetNode: (node: VssNode) -> Unit = { } + var onSubscribeNode: (node: VssNode) -> Unit = { } + var onUnsubscribeNode: (node: VssNode) -> Unit = { } - var subscribedSpecifications = mutableStateListOf() + var subscribedNodes = mutableStateListOf() val isSubscribed by derivedStateOf { - subscribedSpecifications.contains(specification) + subscribedNodes.contains(node) } private val vssVehicle = VssVehicle() - val specifications = listOf(vssVehicle) + vssVehicle.heritage + val vssNodes = listOf(vssVehicle) + vssVehicle.heritage - var specification: VssNode by mutableStateOf(vssVehicle) + var node: VssNode by mutableStateOf(vssVehicle) private set - fun updateSpecification(specification: VssNode) { - this.specification = specification + fun updateNode(node: VssNode) { + this.node = node } } diff --git a/docs/QUICKSTART.md b/docs/QUICKSTART.md index 1fe67495..3ad3c699 100644 --- a/docs/QUICKSTART.md +++ b/docs/QUICKSTART.md @@ -152,7 +152,7 @@ void subscribe() { } ``` -## Specifications Symbol Processing +## VSS Symbol Processing The generic nature of using the `Property` API will result into an information loss of the type which can be seen in the `subscribe` example. You may choose to reuse the same listener for multiple properties. Then it requires an additional check @@ -178,7 +178,7 @@ vssProcessor { } ``` -Use the [`VssModelGenerator`](https://github.com/eclipse-kuksa/kuksa-android-sdk/blob/main/vss-core/src/main/java/org/eclipse/kuksa/vsscore/annotation/VssModelGenerator.kt) annotation and provide the path to the specification file (Inside the assets folder). +Use the [`VssModelGenerator`](https://github.com/eclipse-kuksa/kuksa-android-sdk/blob/main/vss-core/src/main/java/org/eclipse/kuksa/vsscore/annotation/VssModelGenerator.kt) annotation and provide the path to the VSS file (Inside the assets folder). Doing so will generate a complete tree of Kotlin models which can be used in combination with the SDK API. This way you can work with safe types and the SDK takes care of all the model parsing for you. There is also a whole set of convenience operators and extension methods to work with to manipulate the tree data. See the `VssNode` class documentation for this. @@ -188,10 +188,10 @@ convenience operators and extension methods to work with to manipulate the tree class Activity ``` > [!IMPORTANT] -> Keep in mind to always synchronize the specification file between the client and the Databroker. +> Keep in mind to always synchronize the VSS file between the client and the Databroker. -*Example .yaml specification file* +*Example .yaml VSS file* ```yaml Vehicle.Speed: datatype: float @@ -206,7 +206,7 @@ Vehicle.Speed: ```kotlin data class VssSpeed @JvmOverloads constructor( override val `value`: Float = 0f, -) : VssProperty { +) : VssNode { override val comment: String get() = "" @@ -230,7 +230,7 @@ data class VssSpeed @JvmOverloads constructor( } ``` -### Specification API +### API for generated VSS models *Kotlin* ```kotlin @@ -309,7 +309,7 @@ void subscribe() { Collections.singleton(Types.Field.FIELD_VALUE), new VssNodeListener() { @Override - public void onSpecificationChanged(@NonNull VssVehicle.VssSpeed vssNode) { + public void onNodeChanged(@NonNull VssVehicle.VssSpeed vssNode) { Float speed = vssNode.getValue(); } diff --git a/kuksa-sdk/src/main/kotlin/org/eclipse/kuksa/connectivity/databroker/DataBrokerConnection.kt b/kuksa-sdk/src/main/kotlin/org/eclipse/kuksa/connectivity/databroker/DataBrokerConnection.kt index bd9ea303..9d1638f7 100644 --- a/kuksa-sdk/src/main/kotlin/org/eclipse/kuksa/connectivity/databroker/DataBrokerConnection.kt +++ b/kuksa-sdk/src/main/kotlin/org/eclipse/kuksa/connectivity/databroker/DataBrokerConnection.kt @@ -24,14 +24,14 @@ import io.grpc.ManagedChannel import kotlinx.coroutines.CoroutineDispatcher import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.withContext +import org.eclipse.kuksa.connectivity.authentication.JsonWebToken import org.eclipse.kuksa.connectivity.databroker.listener.DisconnectListener import org.eclipse.kuksa.connectivity.databroker.listener.PropertyListener import org.eclipse.kuksa.connectivity.databroker.listener.VssNodeListener -import org.eclipse.kuksa.connectivity.authentication.JsonWebToken import org.eclipse.kuksa.connectivity.databroker.subscription.DataBrokerSubscriber import org.eclipse.kuksa.extension.TAG -import org.eclipse.kuksa.extension.copy import org.eclipse.kuksa.extension.datapoint +import org.eclipse.kuksa.extension.vss.copy import org.eclipse.kuksa.model.Property import org.eclipse.kuksa.pattern.listener.MultiListener import org.eclipse.kuksa.proto.v1.KuksaValV1.GetResponse @@ -42,7 +42,7 @@ import org.eclipse.kuksa.proto.v1.Types.Field import org.eclipse.kuksa.vsscore.model.VssLeaf import org.eclipse.kuksa.vsscore.model.VssNode import org.eclipse.kuksa.vsscore.model.heritage -import org.eclipse.kuksa.vsscore.model.vssProperties +import org.eclipse.kuksa.vsscore.model.vssLeafs import kotlin.properties.Delegates /** @@ -228,9 +228,9 @@ class DataBrokerConnection internal constructor( ): Collection { val responses = mutableListOf() - vssNode.vssProperties.forEach { vssProperty -> - val property = Property(vssProperty.vssPath, fields) - val response = update(property, vssProperty.datapoint) + vssNode.vssLeafs.forEach { vssLeaf -> + val property = Property(vssLeaf.vssPath, fields) + val response = update(property, vssLeaf.datapoint) responses.add(response) } diff --git a/kuksa-sdk/src/main/kotlin/org/eclipse/kuksa/connectivity/databroker/DataBrokerConnector.kt b/kuksa-sdk/src/main/kotlin/org/eclipse/kuksa/connectivity/databroker/DataBrokerConnector.kt index b4f83fb7..1e09d11e 100644 --- a/kuksa-sdk/src/main/kotlin/org/eclipse/kuksa/connectivity/databroker/DataBrokerConnector.kt +++ b/kuksa-sdk/src/main/kotlin/org/eclipse/kuksa/connectivity/databroker/DataBrokerConnector.kt @@ -25,9 +25,9 @@ import kotlinx.coroutines.CoroutineDispatcher import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.delay import kotlinx.coroutines.withContext -import org.eclipse.kuksa.model.TimeoutConfig import org.eclipse.kuksa.connectivity.authentication.JsonWebToken import org.eclipse.kuksa.extension.TAG +import org.eclipse.kuksa.model.TimeoutConfig /** * The DataBrokerConnector is used to establish a successful connection to the DataBroker. The communication takes @@ -38,7 +38,6 @@ class DataBrokerConnector @JvmOverloads constructor( private val jsonWebToken: JsonWebToken? = null, private val defaultDispatcher: CoroutineDispatcher = Dispatchers.Default, ) { - /** * Configuration to be used during connection. */ diff --git a/kuksa-sdk/src/main/kotlin/org/eclipse/kuksa/connectivity/databroker/DataBrokerTransporter.kt b/kuksa-sdk/src/main/kotlin/org/eclipse/kuksa/connectivity/databroker/DataBrokerTransporter.kt index b0f40816..c4607222 100644 --- a/kuksa-sdk/src/main/kotlin/org/eclipse/kuksa/connectivity/databroker/DataBrokerTransporter.kt +++ b/kuksa-sdk/src/main/kotlin/org/eclipse/kuksa/connectivity/databroker/DataBrokerTransporter.kt @@ -29,6 +29,7 @@ import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.withContext import org.eclipse.kuksa.connectivity.authentication.JsonWebToken import org.eclipse.kuksa.connectivity.authentication.withAuthenticationInterceptor +import org.eclipse.kuksa.connectivity.databroker.subscription.DataBrokerSubscription import org.eclipse.kuksa.extension.TAG import org.eclipse.kuksa.extension.applyDatapoint import org.eclipse.kuksa.proto.v1.KuksaValV1 @@ -36,7 +37,6 @@ import org.eclipse.kuksa.proto.v1.KuksaValV1.SubscribeResponse import org.eclipse.kuksa.proto.v1.Types import org.eclipse.kuksa.proto.v1.Types.Field import org.eclipse.kuksa.proto.v1.VALGrpc -import org.eclipse.kuksa.connectivity.databroker.subscription.DataBrokerSubscription /** * Encapsulates the Protobuf-specific interactions with the DataBroker send over gRPC. Provides fetch, update and @@ -134,8 +134,8 @@ internal class DataBrokerTransporter( /** * Sends a request to the DataBroker to subscribe to updates of the specified [vssPath] and [field]. - * Returns a [DataBrokerSubscription] which can be used to register or unregister additional listeners or cancel / closing - * the subscription. + * Returns a [DataBrokerSubscription] which can be used to register or unregister additional listeners or + * cancel / closing the subscription. * * @throws DataBrokerException in case the connection to the DataBroker is no longer active */ diff --git a/kuksa-sdk/src/main/kotlin/org/eclipse/kuksa/connectivity/databroker/subscription/DataBrokerSubscriber.kt b/kuksa-sdk/src/main/kotlin/org/eclipse/kuksa/connectivity/databroker/subscription/DataBrokerSubscriber.kt index 94c4e88d..0e43d7b9 100644 --- a/kuksa-sdk/src/main/kotlin/org/eclipse/kuksa/connectivity/databroker/subscription/DataBrokerSubscriber.kt +++ b/kuksa-sdk/src/main/kotlin/org/eclipse/kuksa/connectivity/databroker/subscription/DataBrokerSubscriber.kt @@ -19,10 +19,10 @@ package org.eclipse.kuksa.connectivity.databroker.subscription import android.util.Log -import org.eclipse.kuksa.connectivity.databroker.listener.PropertyListener -import org.eclipse.kuksa.connectivity.databroker.listener.VssNodeListener import org.eclipse.kuksa.connectivity.databroker.DataBrokerException import org.eclipse.kuksa.connectivity.databroker.DataBrokerTransporter +import org.eclipse.kuksa.connectivity.databroker.listener.PropertyListener +import org.eclipse.kuksa.connectivity.databroker.listener.VssNodeListener import org.eclipse.kuksa.extension.TAG import org.eclipse.kuksa.proto.v1.Types import org.eclipse.kuksa.proto.v1.Types.Field @@ -30,14 +30,15 @@ import org.eclipse.kuksa.vsscore.model.VssLeaf import org.eclipse.kuksa.vsscore.model.VssNode /** - * Creates [DataBrokerSubscription]s to the DataBroker to get notified about changes on the underlying vssPaths and fields. - * If no [DataBrokerSubscription] for a given vssPath and field does exist the DataBrokerSubscriber will create a new one. If it - * was already requested before, the same [DataBrokerSubscription] will be re-used. - * When the last [PropertyListener] of a [DataBrokerSubscription] unsubscribes the [DataBrokerSubscription] will be automatically canceled - * and removed from the active [DataBrokerSubscription]s. + * Creates [DataBrokerSubscription]s to the DataBroker to get notified about changes on the underlying vssPaths and + * fields.If no [DataBrokerSubscription] for a given vssPath and field does exist the DataBrokerSubscriber will create + * a new one. If it was already requested before, the same [DataBrokerSubscription] will be re-used. When the last + * [PropertyListener] of a [DataBrokerSubscription] unsubscribes the [DataBrokerSubscription] will be automatically + * canceled and removed from the active [DataBrokerSubscription]s. */ internal class DataBrokerSubscriber(private val dataBrokerTransporter: DataBrokerTransporter) { - private val subscriptions = mutableMapOf() // String(Subscription#identifier) -> Subscription + private val subscriptions = + mutableMapOf() // String(Subscription#identifier) -> Subscription /** * Checks if the SDK is already subscribed to the corresponding [vssPath] and [field], if the SDK is already @@ -79,36 +80,36 @@ internal class DataBrokerSubscriber(private val dataBrokerTransporter: DataBroke * can be subscribed because they have an actual value. When provided with any parent [VssNode] then this * [subscribe] method will find all [VssLeaf] children and subscribes them instead. Once subscribed the * application will be notified about any changes to every subscribed [VssLeaf]. The [field] can be used to - * subscribe to different information of the [specification]. The default for the [field] parameter is a single + * subscribe to different information of the [node]. The default for the [field] parameter is a single * [Types.Field.FIELD_VALUE] entry. * * @throws DataBrokerException in case the connection to the DataBroker is no longer active */ fun subscribe( - specification: T, + node: T, field: Field = Field.FIELD_VALUE, listener: VssNodeListener, ) { - val vssPath = specification.vssPath + val vssPath = node.vssPath - val specificationPropertyListener = SpecificationPropertyListener(specification, listener) + val specificationPropertyListener = SpecificationPropertyListener(node, listener) subscribe(vssPath, field, specificationPropertyListener) } /** - * Removes the specified [listener] for the specified [specification] and [field] from an already existing + * Removes the specified [listener] for the specified [node] and [field] from an already existing * Subscription to the DataBroker. If the given Subscription has no more Listeners after unsubscribing it will be - * canceled and removed. Gracefully ignores invalid input, e.g. when a [specification] and [field] of a + * canceled and removed. Gracefully ignores invalid input, e.g. when a [node] and [field] of a * non-subscribed property is provided. */ fun unsubscribe( - specification: T, + node: T, field: Field = Field.FIELD_VALUE, listener: VssNodeListener, ) { - val vssPath = specification.vssPath + val vssPath = node.vssPath - val specificationPropertyListener = SpecificationPropertyListener(specification, listener) + val specificationPropertyListener = SpecificationPropertyListener(node, listener) unsubscribe(vssPath, field, specificationPropertyListener) } diff --git a/kuksa-sdk/src/main/kotlin/org/eclipse/kuksa/connectivity/databroker/subscription/SpecificationPropertyListener.kt b/kuksa-sdk/src/main/kotlin/org/eclipse/kuksa/connectivity/databroker/subscription/SpecificationPropertyListener.kt index 38e7540c..774b49bc 100644 --- a/kuksa-sdk/src/main/kotlin/org/eclipse/kuksa/connectivity/databroker/subscription/SpecificationPropertyListener.kt +++ b/kuksa-sdk/src/main/kotlin/org/eclipse/kuksa/connectivity/databroker/subscription/SpecificationPropertyListener.kt @@ -20,7 +20,7 @@ package org.eclipse.kuksa.connectivity.databroker.subscription import org.eclipse.kuksa.connectivity.databroker.listener.PropertyListener import org.eclipse.kuksa.connectivity.databroker.listener.VssNodeListener -import org.eclipse.kuksa.extension.copy +import org.eclipse.kuksa.extension.vss.copy import org.eclipse.kuksa.proto.v1.KuksaValV1 import org.eclipse.kuksa.vsscore.model.VssNode diff --git a/kuksa-sdk/src/main/kotlin/org/eclipse/kuksa/extension/VssSpecificationExtension.kt b/kuksa-sdk/src/main/kotlin/org/eclipse/kuksa/extension/VssSpecificationExtension.kt index a4d2bccd..825581dc 100644 --- a/kuksa-sdk/src/main/kotlin/org/eclipse/kuksa/extension/VssSpecificationExtension.kt +++ b/kuksa-sdk/src/main/kotlin/org/eclipse/kuksa/extension/VssSpecificationExtension.kt @@ -22,7 +22,7 @@ import org.eclipse.kuksa.model.Property import org.eclipse.kuksa.proto.v1.Types import org.eclipse.kuksa.vsscore.model.VssLeaf import org.eclipse.kuksa.vsscore.model.VssNode -import org.eclipse.kuksa.vsscore.model.vssProperties +import org.eclipse.kuksa.vsscore.model.vssLeafs /** * Finds all [VssLeaf] heirs for the [VssNode] and converts them into a collection of [Property]. @@ -30,6 +30,6 @@ import org.eclipse.kuksa.vsscore.model.vssProperties fun VssNode.createProperties( vararg fields: Types.Field = arrayOf(Types.Field.FIELD_VALUE), ): Collection { - return vssProperties + return vssLeafs .map { Property(it.vssPath, fields.toSet()) } } diff --git a/kuksa-sdk/src/main/kotlin/org/eclipse/kuksa/extension/vssProperty/VssPropertyBooleanExtension.kt b/kuksa-sdk/src/main/kotlin/org/eclipse/kuksa/extension/vss/VssLeafBooleanExtension.kt similarity index 92% rename from kuksa-sdk/src/main/kotlin/org/eclipse/kuksa/extension/vssProperty/VssPropertyBooleanExtension.kt rename to kuksa-sdk/src/main/kotlin/org/eclipse/kuksa/extension/vss/VssLeafBooleanExtension.kt index 0bafa2f6..7b75eeba 100644 --- a/kuksa-sdk/src/main/kotlin/org/eclipse/kuksa/extension/vssProperty/VssPropertyBooleanExtension.kt +++ b/kuksa-sdk/src/main/kotlin/org/eclipse/kuksa/extension/vss/VssLeafBooleanExtension.kt @@ -16,9 +16,8 @@ * SPDX-License-Identifier: Apache-2.0 */ -package org.eclipse.kuksa.extension.vssProperty +package org.eclipse.kuksa.extension.vss -import org.eclipse.kuksa.extension.copy import org.eclipse.kuksa.vsscore.model.VssLeaf /** diff --git a/kuksa-sdk/src/main/kotlin/org/eclipse/kuksa/extension/vssProperty/VssPropertyDoubleExtension.kt b/kuksa-sdk/src/main/kotlin/org/eclipse/kuksa/extension/vss/VssLeafDoubleExtension.kt similarity index 97% rename from kuksa-sdk/src/main/kotlin/org/eclipse/kuksa/extension/vssProperty/VssPropertyDoubleExtension.kt rename to kuksa-sdk/src/main/kotlin/org/eclipse/kuksa/extension/vss/VssLeafDoubleExtension.kt index 072255af..ed3a405b 100644 --- a/kuksa-sdk/src/main/kotlin/org/eclipse/kuksa/extension/vssProperty/VssPropertyDoubleExtension.kt +++ b/kuksa-sdk/src/main/kotlin/org/eclipse/kuksa/extension/vss/VssLeafDoubleExtension.kt @@ -16,9 +16,8 @@ * SPDX-License-Identifier: Apache-2.0 */ -package org.eclipse.kuksa.extension.vssProperty +package org.eclipse.kuksa.extension.vss -import org.eclipse.kuksa.extension.copy import org.eclipse.kuksa.vsscore.model.VssLeaf /** diff --git a/kuksa-sdk/src/main/kotlin/org/eclipse/kuksa/extension/vssProperty/VssPropertyFloatExtension.kt b/kuksa-sdk/src/main/kotlin/org/eclipse/kuksa/extension/vss/VssLeafFloatExtension.kt similarity index 97% rename from kuksa-sdk/src/main/kotlin/org/eclipse/kuksa/extension/vssProperty/VssPropertyFloatExtension.kt rename to kuksa-sdk/src/main/kotlin/org/eclipse/kuksa/extension/vss/VssLeafFloatExtension.kt index cefadaa7..083bdc2e 100644 --- a/kuksa-sdk/src/main/kotlin/org/eclipse/kuksa/extension/vssProperty/VssPropertyFloatExtension.kt +++ b/kuksa-sdk/src/main/kotlin/org/eclipse/kuksa/extension/vss/VssLeafFloatExtension.kt @@ -16,9 +16,8 @@ * SPDX-License-Identifier: Apache-2.0 */ -package org.eclipse.kuksa.extension.vssProperty +package org.eclipse.kuksa.extension.vss -import org.eclipse.kuksa.extension.copy import org.eclipse.kuksa.vsscore.model.VssLeaf /** diff --git a/kuksa-sdk/src/main/kotlin/org/eclipse/kuksa/extension/vssProperty/VssPropertyIntExtension.kt b/kuksa-sdk/src/main/kotlin/org/eclipse/kuksa/extension/vss/VssLeafIntExtension.kt similarity index 97% rename from kuksa-sdk/src/main/kotlin/org/eclipse/kuksa/extension/vssProperty/VssPropertyIntExtension.kt rename to kuksa-sdk/src/main/kotlin/org/eclipse/kuksa/extension/vss/VssLeafIntExtension.kt index d2b905bb..b0e74aeb 100644 --- a/kuksa-sdk/src/main/kotlin/org/eclipse/kuksa/extension/vssProperty/VssPropertyIntExtension.kt +++ b/kuksa-sdk/src/main/kotlin/org/eclipse/kuksa/extension/vss/VssLeafIntExtension.kt @@ -16,9 +16,8 @@ * SPDX-License-Identifier: Apache-2.0 */ -package org.eclipse.kuksa.extension.vssProperty +package org.eclipse.kuksa.extension.vss -import org.eclipse.kuksa.extension.copy import org.eclipse.kuksa.vsscore.model.VssLeaf /** diff --git a/kuksa-sdk/src/main/kotlin/org/eclipse/kuksa/extension/vssProperty/VssPropertyLongExtension.kt b/kuksa-sdk/src/main/kotlin/org/eclipse/kuksa/extension/vss/VssLeafLongExtension.kt similarity index 97% rename from kuksa-sdk/src/main/kotlin/org/eclipse/kuksa/extension/vssProperty/VssPropertyLongExtension.kt rename to kuksa-sdk/src/main/kotlin/org/eclipse/kuksa/extension/vss/VssLeafLongExtension.kt index d8bf749c..87c53569 100644 --- a/kuksa-sdk/src/main/kotlin/org/eclipse/kuksa/extension/vssProperty/VssPropertyLongExtension.kt +++ b/kuksa-sdk/src/main/kotlin/org/eclipse/kuksa/extension/vss/VssLeafLongExtension.kt @@ -16,9 +16,8 @@ * SPDX-License-Identifier: Apache-2.0 */ -package org.eclipse.kuksa.extension.vssProperty +package org.eclipse.kuksa.extension.vss -import org.eclipse.kuksa.extension.copy import org.eclipse.kuksa.vsscore.model.VssLeaf /** diff --git a/kuksa-sdk/src/main/kotlin/org/eclipse/kuksa/extension/VssSpecificationCopyExtension.kt b/kuksa-sdk/src/main/kotlin/org/eclipse/kuksa/extension/vss/VssNodeCopyExtension.kt similarity index 93% rename from kuksa-sdk/src/main/kotlin/org/eclipse/kuksa/extension/VssSpecificationCopyExtension.kt rename to kuksa-sdk/src/main/kotlin/org/eclipse/kuksa/extension/vss/VssNodeCopyExtension.kt index 04da6128..9f0099e9 100644 --- a/kuksa-sdk/src/main/kotlin/org/eclipse/kuksa/extension/VssSpecificationCopyExtension.kt +++ b/kuksa-sdk/src/main/kotlin/org/eclipse/kuksa/extension/vss/VssNodeCopyExtension.kt @@ -14,11 +14,11 @@ * limitations under the License. * * SPDX-License-Identifier: Apache-2.0 - * */ -package org.eclipse.kuksa.extension +package org.eclipse.kuksa.extension.vss +import org.eclipse.kuksa.extension.copy import org.eclipse.kuksa.proto.v1.Types import org.eclipse.kuksa.proto.v1.Types.Datapoint import org.eclipse.kuksa.proto.v1.Types.Datapoint.ValueCase.* @@ -51,7 +51,7 @@ import kotlin.reflect.full.memberProperties // https://detekt.dev/docs/rules/performance/ @Suppress("performance:SpreadOperator") fun T.deepCopy(generation: Int = 0, vararg changedHeritage: VssNode): T { - if (generation == changedHeritage.size) { // Reached the end, use the changed VssProperty + if (generation == changedHeritage.size) { // Reached the end, use the changed [VssLeaf] return this } @@ -63,9 +63,9 @@ fun T.deepCopy(generation: Int = 0, vararg changedHeritage: VssNod .ifEmpty { changedHeritage } } - val childSpecification = heritageLine[generation] - val childCopy = childSpecification.deepCopy(generation + 1, *heritageLine) - val parameterNameToChild = mapOf(childSpecification.variableName to childCopy) + val childNode = heritageLine[generation] + val childCopy = childNode.deepCopy(generation + 1, *heritageLine) + val parameterNameToChild = mapOf(childNode.variableName to childCopy) return copy(parameterNameToChild) } @@ -154,16 +154,16 @@ fun T.copy( consideredHeritage: Collection = heritage, ): T { val vssNodes = consideredHeritage + this - val vssProperty = vssNodes + val vssNode = vssNodes .filterIsInstance>() .find { it.vssPath == vssPath } ?: return this - val updatedVssProperty = vssProperty.copy(updatedValue) + val updatedVssNode = vssNode.copy(updatedValue) // Same property with no heirs, no deep copy is needed - if (this.vssPath == updatedVssProperty.vssPath) return updatedVssProperty as T + if (this.vssPath == updatedVssNode.vssPath) return updatedVssNode as T - return deepCopy(0, updatedVssProperty) + return deepCopy(0, updatedVssNode) } // region Operators diff --git a/kuksa-sdk/src/main/kotlin/org/eclipse/kuksa/model/Property.kt b/kuksa-sdk/src/main/kotlin/org/eclipse/kuksa/model/Property.kt index 57aece91..b9a11f27 100644 --- a/kuksa-sdk/src/main/kotlin/org/eclipse/kuksa/model/Property.kt +++ b/kuksa-sdk/src/main/kotlin/org/eclipse/kuksa/model/Property.kt @@ -27,7 +27,7 @@ import org.eclipse.kuksa.proto.v1.Types.Field.FIELD_VALUE */ data class Property( /** - * The VehicleSignalSpecification path. + * The VehicleSignalSpecification (VSS) path. */ val vssPath: String, diff --git a/kuksa-sdk/src/test/kotlin/org/eclipse/kuksa/connectivity/databroker/DataBrokerConnectorProvider.kt b/kuksa-sdk/src/test/kotlin/org/eclipse/kuksa/connectivity/databroker/DataBrokerConnectorProvider.kt index 0e5cec2b..53df36bb 100644 --- a/kuksa-sdk/src/test/kotlin/org/eclipse/kuksa/connectivity/databroker/DataBrokerConnectorProvider.kt +++ b/kuksa-sdk/src/test/kotlin/org/eclipse/kuksa/connectivity/databroker/DataBrokerConnectorProvider.kt @@ -23,8 +23,8 @@ import io.grpc.Grpc import io.grpc.ManagedChannel import io.grpc.ManagedChannelBuilder import io.grpc.TlsChannelCredentials -import org.eclipse.kuksa.model.TimeoutConfig import org.eclipse.kuksa.connectivity.authentication.JsonWebToken +import org.eclipse.kuksa.model.TimeoutConfig import java.io.IOException import java.io.InputStream diff --git a/kuksa-sdk/src/test/kotlin/org/eclipse/kuksa/vssNode/VssNodeArithmeticTest.kt b/kuksa-sdk/src/test/kotlin/org/eclipse/kuksa/vssNode/VssNodeArithmeticTest.kt index 6bb8d052..04387424 100644 --- a/kuksa-sdk/src/test/kotlin/org/eclipse/kuksa/vssNode/VssNodeArithmeticTest.kt +++ b/kuksa-sdk/src/test/kotlin/org/eclipse/kuksa/vssNode/VssNodeArithmeticTest.kt @@ -22,10 +22,10 @@ import io.kotest.assertions.throwables.shouldThrow import io.kotest.core.spec.style.BehaviorSpec import io.kotest.matchers.shouldBe import io.kotest.matchers.string.shouldStartWith -import org.eclipse.kuksa.extension.vssProperty.div -import org.eclipse.kuksa.extension.vssProperty.minus -import org.eclipse.kuksa.extension.vssProperty.plus -import org.eclipse.kuksa.extension.vssProperty.times +import org.eclipse.kuksa.extension.vss.div +import org.eclipse.kuksa.extension.vss.minus +import org.eclipse.kuksa.extension.vss.plus +import org.eclipse.kuksa.extension.vss.times import org.eclipse.kuksa.test.kotest.Unit class VssNodeArithmeticTest : BehaviorSpec({ diff --git a/kuksa-sdk/src/test/kotlin/org/eclipse/kuksa/vssNode/VssNodeCopyTest.kt b/kuksa-sdk/src/test/kotlin/org/eclipse/kuksa/vssNode/VssNodeCopyTest.kt index b47a096b..ba81c39a 100644 --- a/kuksa-sdk/src/test/kotlin/org/eclipse/kuksa/vssNode/VssNodeCopyTest.kt +++ b/kuksa-sdk/src/test/kotlin/org/eclipse/kuksa/vssNode/VssNodeCopyTest.kt @@ -24,10 +24,10 @@ import io.kotest.core.spec.style.BehaviorSpec import io.kotest.matchers.shouldBe import io.kotest.matchers.string.shouldStartWith import io.kotest.matchers.types.shouldBeSameInstanceAs -import org.eclipse.kuksa.extension.copy -import org.eclipse.kuksa.extension.deepCopy -import org.eclipse.kuksa.extension.invoke -import org.eclipse.kuksa.extension.vssProperty.not +import org.eclipse.kuksa.extension.vss.copy +import org.eclipse.kuksa.extension.vss.deepCopy +import org.eclipse.kuksa.extension.vss.invoke +import org.eclipse.kuksa.extension.vss.not import org.eclipse.kuksa.proto.v1.Types import org.eclipse.kuksa.test.kotest.Unit import org.eclipse.kuksa.vsscore.model.VssLeaf diff --git a/samples/src/main/java/com/example/sample/JavaActivity.java b/samples/src/main/java/com/example/sample/JavaActivity.java index 67b0133b..c6376b34 100644 --- a/samples/src/main/java/com/example/sample/JavaActivity.java +++ b/samples/src/main/java/com/example/sample/JavaActivity.java @@ -194,7 +194,7 @@ public void onError(@NonNull Throwable throwable) { } // region: Specifications - public void fetchSpecification() { + public void fetchNode() { if (dataBrokerConnection == null) return; VssVehicle.VssSpeed vssSpeed = new VssVehicle.VssSpeed(); @@ -217,7 +217,7 @@ public void onError(@NonNull Throwable error) { ); } - public void updateSpecification() { + public void updateNode() { if (dataBrokerConnection == null) return; VssVehicle.VssSpeed vssSpeed = new VssVehicle.VssSpeed(100f); @@ -238,7 +238,7 @@ public void onError(@NonNull Throwable error) { ); } - public void subscribeSpecification() { + public void subscribeNode() { if (dataBrokerConnection == null) return; VssVehicle.VssSpeed vssSpeed = new VssVehicle.VssSpeed(); diff --git a/samples/src/main/kotlin/com/example/sample/KotlinActivity.kt b/samples/src/main/kotlin/com/example/sample/KotlinActivity.kt index f1131378..f8666fb8 100644 --- a/samples/src/main/kotlin/com/example/sample/KotlinActivity.kt +++ b/samples/src/main/kotlin/com/example/sample/KotlinActivity.kt @@ -26,13 +26,13 @@ import io.grpc.Grpc import io.grpc.ManagedChannelBuilder import io.grpc.TlsChannelCredentials import kotlinx.coroutines.launch +import org.eclipse.kuksa.connectivity.authentication.JsonWebToken import org.eclipse.kuksa.connectivity.databroker.DataBrokerConnection import org.eclipse.kuksa.connectivity.databroker.DataBrokerConnector import org.eclipse.kuksa.connectivity.databroker.DataBrokerException import org.eclipse.kuksa.connectivity.databroker.listener.DisconnectListener import org.eclipse.kuksa.connectivity.databroker.listener.PropertyListener import org.eclipse.kuksa.connectivity.databroker.listener.VssNodeListener -import org.eclipse.kuksa.connectivity.authentication.JsonWebToken import org.eclipse.kuksa.model.Property import org.eclipse.kuksa.proto.v1.KuksaValV1 import org.eclipse.kuksa.proto.v1.Types @@ -159,8 +159,8 @@ class KotlinActivity : AppCompatActivity() { dataBrokerConnection?.subscribe(property, propertyListener) } - // region: Specifications - fun fetchSpecification() { + // region: VSS generated models + fun fetchNode() { lifecycleScope.launch { try { val vssSpeed = VssVehicle.VssSpeed() @@ -172,19 +172,19 @@ class KotlinActivity : AppCompatActivity() { } } - fun updateSpecification() { + fun updateNode() { lifecycleScope.launch { val vssSpeed = VssVehicle.VssSpeed(value = 100f) dataBrokerConnection?.update(vssSpeed, listOf(Types.Field.FIELD_VALUE)) } } - fun subscribeSpecification() { + fun subscribeNode() { val vssSpeed = VssVehicle.VssSpeed(value = 100f) dataBrokerConnection?.subscribe( vssSpeed, listOf(Types.Field.FIELD_VALUE), - listener = object : VssNodeListener { + object : VssNodeListener { override fun onNodeChanged(vssNode: VssVehicle.VssSpeed) { val speed = vssSpeed.value } diff --git a/vss-core/src/main/java/org/eclipse/kuksa/vsscore/annotation/VssModelGenerator.kt b/vss-core/src/main/kotlin/org/eclipse/kuksa/vsscore/annotation/VssModelGenerator.kt similarity index 100% rename from vss-core/src/main/java/org/eclipse/kuksa/vsscore/annotation/VssModelGenerator.kt rename to vss-core/src/main/kotlin/org/eclipse/kuksa/vsscore/annotation/VssModelGenerator.kt diff --git a/vss-core/src/main/java/org/eclipse/kuksa/vsscore/extension/StringExtension.kt b/vss-core/src/main/kotlin/org/eclipse/kuksa/vsscore/extension/StringExtension.kt similarity index 100% rename from vss-core/src/main/java/org/eclipse/kuksa/vsscore/extension/StringExtension.kt rename to vss-core/src/main/kotlin/org/eclipse/kuksa/vsscore/extension/StringExtension.kt diff --git a/vss-core/src/main/java/org/eclipse/kuksa/vsscore/model/VssNode.kt b/vss-core/src/main/kotlin/org/eclipse/kuksa/vsscore/model/VssNode.kt similarity index 99% rename from vss-core/src/main/java/org/eclipse/kuksa/vsscore/model/VssNode.kt rename to vss-core/src/main/kotlin/org/eclipse/kuksa/vsscore/model/VssNode.kt index 3a790065..25d5e9cc 100644 --- a/vss-core/src/main/java/org/eclipse/kuksa/vsscore/model/VssNode.kt +++ b/vss-core/src/main/kotlin/org/eclipse/kuksa/vsscore/model/VssNode.kt @@ -115,7 +115,7 @@ val VssNode.heritage: Collection /** * Finds the latest generation in the form of [VssLeaf] for the current [VssNode]. */ -val VssNode.vssProperties: Collection> +val VssNode.vssLeafs: Collection> get() = heritage .ifEmpty { setOf(this) } .filterIsInstance>() diff --git a/vss-processor-plugin/src/main/java/org/eclipse/kuksa/vssprocessor/plugin/VssProcessorPlugin.kt b/vss-processor-plugin/src/main/java/org/eclipse/kuksa/vssprocessor/plugin/VssProcessorPlugin.kt index 2a119a17..ae307ed4 100644 --- a/vss-processor-plugin/src/main/java/org/eclipse/kuksa/vssprocessor/plugin/VssProcessorPlugin.kt +++ b/vss-processor-plugin/src/main/java/org/eclipse/kuksa/vssprocessor/plugin/VssProcessorPlugin.kt @@ -54,7 +54,7 @@ internal constructor(objectFactory: ObjectFactory) { private val fileSeparator = File.separator /** - * This Plugin searches for compatible specification files and copies them into an input folder for the + * This Plugin searches for compatible VSS files and copies them into an input folder for the * KSP VSS Processor. This is necessary because the Symbol Processor does not have access to the android assets folder. */ class VssProcessorPlugin : Plugin { diff --git a/vss-processor/src/main/kotlin/org/eclipse/kuksa/vssprocessor/spec/VssNodeSpecModel.kt b/vss-processor/src/main/kotlin/org/eclipse/kuksa/vssprocessor/spec/VssNodeSpecModel.kt index 9c03f7e6..5f3e497c 100644 --- a/vss-processor/src/main/kotlin/org/eclipse/kuksa/vssprocessor/spec/VssNodeSpecModel.kt +++ b/vss-processor/src/main/kotlin/org/eclipse/kuksa/vssprocessor/spec/VssNodeSpecModel.kt @@ -124,10 +124,10 @@ internal class VssNodeSpecModel( // Final leafs should ONLY implement the vss property interface superInterfaces.clear() - val vssPropertyInterface = VssLeaf::class + val vssLeafInterface = VssLeaf::class .asTypeName() .plusParameter(datatypeProperty) - superInterfaces.add(vssPropertyInterface) + superInterfaces.add(vssLeafInterface) } val propertySpec = createVssNodeSpecs(className, packageName = packageName) diff --git a/vss-processor/src/test/kotlin/org/eclipse/kuksa/vssprocessor/parser/YamlDefinitionParserTest.kt b/vss-processor/src/test/kotlin/org/eclipse/kuksa/vssprocessor/parser/YamlVssParserTest.kt similarity index 60% rename from vss-processor/src/test/kotlin/org/eclipse/kuksa/vssprocessor/parser/YamlDefinitionParserTest.kt rename to vss-processor/src/test/kotlin/org/eclipse/kuksa/vssprocessor/parser/YamlVssParserTest.kt index d8bdd514..03f90ecc 100644 --- a/vss-processor/src/test/kotlin/org/eclipse/kuksa/vssprocessor/parser/YamlDefinitionParserTest.kt +++ b/vss-processor/src/test/kotlin/org/eclipse/kuksa/vssprocessor/parser/YamlVssParserTest.kt @@ -22,47 +22,53 @@ import io.kotest.core.spec.style.BehaviorSpec import io.kotest.matchers.shouldBe import java.io.File -class YamlDefinitionParserTest : BehaviorSpec({ +class YamlVssParserTest : BehaviorSpec({ given("A parser for yaml files") { val parser = YamlVssParser() val classLoader = parser::class.java.classLoader!! - and("a specification file of version 4") { - val resourceUrl = classLoader.getResource("vss_rel_4.0.yaml")!! - val specificationFile = File(resourceUrl.path) + and("a VSS file of version 4") { + val resourceUrl = classLoader.getResource(VALID_VSS_FILE_NAME)!! + val vssFile = File(resourceUrl.path) `when`("parsing the file") { - val parsedSpecifications = parser.parseNodes(specificationFile) + val parsedNodes = parser.parseNodes(vssFile) - then("the correct number of specification models should be parsed") { - // These are exactly the specifications defined in the 4.0 file - parsedSpecifications.size shouldBe 1197 + then("the correct number of VSS models should be parsed") { + // These are exactly the VSS models defined in the 4.0 file + parsedNodes.size shouldBe 1197 } } } and("an incompatible yaml file") { - val incompatibleResourceUrl = classLoader.getResource("incompatible.yaml")!! + val incompatibleResourceUrl = classLoader.getResource(INCOMPATIBLE_VSS_FILE_NAME)!! val incompatibleFile = File(incompatibleResourceUrl.path) `when`("parsing the file") { - val parsedSpecifications = parser.parseNodes(incompatibleFile) + val parsedNodes = parser.parseNodes(incompatibleFile) then("no entries should be returned") { - parsedSpecifications.size shouldBe 0 + parsedNodes.size shouldBe 0 } } } and("an invalid yaml file") { - val invalidResourceUrl = classLoader.getResource("invalid.yaml")!! + val invalidResourceUrl = classLoader.getResource(INVALID_VSS_FILE_NAME)!! val invalidFile = File(invalidResourceUrl.path) `when`("parsing the file") { - val parsedSpecifications = parser.parseNodes(invalidFile) + val parsedNodes = parser.parseNodes(invalidFile) then("no entries should be returned") { - parsedSpecifications.size shouldBe 0 + parsedNodes.size shouldBe 0 } } } } -}) +}) { + companion object { + private const val VALID_VSS_FILE_NAME = "vss_rel_4.0.yaml" + private const val INVALID_VSS_FILE_NAME = "invalid.yaml" + private const val INCOMPATIBLE_VSS_FILE_NAME = "incompatible.yaml" + } +} From c359191d50d19c1ec93d80ce2c4fae84bc0fd8a8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mark=20Hu=CC=88sers?= Date: Fri, 1 Mar 2024 16:39:05 +0100 Subject: [PATCH 09/20] chore: Update AGP + Compose versions --- gradle/libs.versions.toml | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/gradle/libs.versions.toml b/gradle/libs.versions.toml index 7bc3a432..79b171bd 100644 --- a/gradle/libs.versions.toml +++ b/gradle/libs.versions.toml @@ -1,6 +1,6 @@ [versions] activityKtx = "1.8.2" -androidGradlePlugin = "8.2.2" # Check with detekt table first: https://detekt.dev/docs/introduction/compatibility/ +androidGradlePlugin = "8.3.0" # Check with detekt table first: https://detekt.dev/docs/introduction/compatibility/ detekt = "1.23.5" datastore = "1.0.0" constraintlayoutCompose = "1.0.1" @@ -9,7 +9,7 @@ dokka = "1.9.10" kotlin = "1.9.22" kotlinpoet = "1.16.0" kotlinxSerializationJson = "1.6.1" -runtimeLivedata = "1.6.0" +runtimeLivedata = "1.6.2" symbolProcessingApi = "1.9.22-1.0.17" tomcatAnnotations = "6.0.53" ktlint = "0.0" # Maintained inside ktlint.gradle.kts @@ -22,7 +22,7 @@ mockk = "1.13.7" androidxLifecycle = "2.7.0" kotlinxCoroutines = "1.7.3" kotlinCompilerExtension = "1.5.9" -composeBom = "2024.01.00" +composeBom = "2024.02.01" jvmTarget = "17" [libraries] From ea1054d406e83af45abad28bcc4539e8abe060a6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mark=20Hu=CC=88sers?= Date: Mon, 4 Mar 2024 18:49:58 +0100 Subject: [PATCH 10/20] chore: Replace Property with DataBrokerRequests The "Property" name was not a good reflection of the combination of the variables vssPath + Field (grpc). This model is not replaced with explicit *Request classes. BREAKING CHANGE: The API for fetch / subscribe / update did change. The input for these methods are now wrapped via "DataBrokerRequest" classes e.g. "FetchRequest", "UpdateRequest". For generated VSS models the classes "VssNodeFetchRequest" etc. should be used. - The Property model was removed in favor of DataBrokerRequest --- README.md | 4 +- .../databroker/JavaDataBrokerEngine.java | 50 +++----- .../kuksa/testapp/KuksaDataBrokerActivity.kt | 117 +++++++++++------- .../testapp/databroker/DataBrokerEngine.kt | 22 ++-- .../databroker/KotlinDataBrokerEngine.kt | 35 +++--- .../testapp/databroker/view/DataBrokerView.kt | 62 +++++----- .../{VssViewModel.kt => VssNodesViewModel.kt} | 2 +- .../viewmodel/VssPropertiesViewModel.kt | 34 ++--- docs/QUICKSTART.md | 49 ++++---- .../databroker/DataBrokerConnection.kt | 100 +++++++-------- .../databroker/DataBrokerTransporter.kt | 6 +- .../databroker/listener/PropertyListener.kt | 4 +- .../databroker/request/DataBrokerRequest.kt} | 16 +-- .../databroker/request/FetchRequest.kt | 29 +++++ .../databroker/request/SubscribeRequest.kt | 29 +++++ .../databroker/request/UpdateRequest.kt | 31 +++++ .../request/VssNodeDataBrokerRequest.kt | 32 +++++ .../request/VssNodeFetchRequest.kt} | 19 ++- .../request/VssNodeSubscribeRequest.kt | 32 +++++ .../request/VssNodeUpdateRequest.kt | 32 +++++ .../DataBrokerConnectorAuthenticationTest.kt | 42 +++---- .../databroker/DataBrokerConnectionTest.kt | 77 +++++++----- .../databroker/DataBrokerTransporterTest.kt | 12 +- .../subscription/DataBrokerSubscriberTest.kt | 2 +- .../DataBrokerTransporterExtensions.kt | 12 +- .../java/com/example/sample/JavaActivity.java | 53 +++++--- .../com/example/sample/KotlinActivity.kt | 35 ++++-- .../eclipse/kuksa/vsscore/model/VssNode.kt | 30 ++++- 28 files changed, 617 insertions(+), 351 deletions(-) rename app/src/main/kotlin/org/eclipse/kuksa/testapp/databroker/viewmodel/{VssViewModel.kt => VssNodesViewModel.kt} (97%) rename kuksa-sdk/src/main/kotlin/org/eclipse/kuksa/{model/Property.kt => connectivity/databroker/request/DataBrokerRequest.kt} (67%) create mode 100644 kuksa-sdk/src/main/kotlin/org/eclipse/kuksa/connectivity/databroker/request/FetchRequest.kt create mode 100644 kuksa-sdk/src/main/kotlin/org/eclipse/kuksa/connectivity/databroker/request/SubscribeRequest.kt create mode 100644 kuksa-sdk/src/main/kotlin/org/eclipse/kuksa/connectivity/databroker/request/UpdateRequest.kt create mode 100644 kuksa-sdk/src/main/kotlin/org/eclipse/kuksa/connectivity/databroker/request/VssNodeDataBrokerRequest.kt rename kuksa-sdk/src/main/kotlin/org/eclipse/kuksa/{extension/VssSpecificationExtension.kt => connectivity/databroker/request/VssNodeFetchRequest.kt} (59%) create mode 100644 kuksa-sdk/src/main/kotlin/org/eclipse/kuksa/connectivity/databroker/request/VssNodeSubscribeRequest.kt create mode 100644 kuksa-sdk/src/main/kotlin/org/eclipse/kuksa/connectivity/databroker/request/VssNodeUpdateRequest.kt diff --git a/README.md b/README.md index b2a7b4df..0fc3e670 100644 --- a/README.md +++ b/README.md @@ -57,8 +57,8 @@ fun connectInsecure(host: String, port: Int) { ```kotlin fun fetch() { lifecycleScope.launch { - val property = Property("Vehicle.Speed", listOf(Field.FIELD_VALUE)) - val response = dataBrokerConnection?.fetch(property) ?: return@launch + val request = FetchRequest("Vehicle.Speed", listOf(Field.FIELD_VALUE)) + val response = dataBrokerConnection?.fetch(request) ?: return@launch val entry = entriesList.first() // Don't forget to handle empty responses val value = entry.value val speed = value.float diff --git a/app/src/main/java/org/eclipse/kuksa/testapp/databroker/JavaDataBrokerEngine.java b/app/src/main/java/org/eclipse/kuksa/testapp/databroker/JavaDataBrokerEngine.java index cee2dbed..d99ccf4a 100644 --- a/app/src/main/java/org/eclipse/kuksa/testapp/databroker/JavaDataBrokerEngine.java +++ b/app/src/main/java/org/eclipse/kuksa/testapp/databroker/JavaDataBrokerEngine.java @@ -23,22 +23,23 @@ import androidx.annotation.NonNull; -import org.eclipse.kuksa.coroutine.CoroutineCallback; import org.eclipse.kuksa.connectivity.databroker.DataBrokerConnection; import org.eclipse.kuksa.connectivity.databroker.DataBrokerConnector; import org.eclipse.kuksa.connectivity.databroker.listener.DisconnectListener; import org.eclipse.kuksa.connectivity.databroker.listener.PropertyListener; import org.eclipse.kuksa.connectivity.databroker.listener.VssNodeListener; -import org.eclipse.kuksa.model.Property; +import org.eclipse.kuksa.connectivity.databroker.request.FetchRequest; +import org.eclipse.kuksa.connectivity.databroker.request.SubscribeRequest; +import org.eclipse.kuksa.connectivity.databroker.request.UpdateRequest; +import org.eclipse.kuksa.connectivity.databroker.request.VssNodeFetchRequest; +import org.eclipse.kuksa.connectivity.databroker.request.VssNodeSubscribeRequest; +import org.eclipse.kuksa.coroutine.CoroutineCallback; import org.eclipse.kuksa.proto.v1.KuksaValV1.GetResponse; import org.eclipse.kuksa.proto.v1.KuksaValV1.SetResponse; -import org.eclipse.kuksa.proto.v1.Types; -import org.eclipse.kuksa.proto.v1.Types.Datapoint; import org.eclipse.kuksa.testapp.databroker.connection.DataBrokerConnectorFactory; import org.eclipse.kuksa.testapp.databroker.model.ConnectionInfo; import org.eclipse.kuksa.vsscore.model.VssNode; -import java.util.ArrayList; import java.util.HashSet; import java.util.Set; @@ -91,7 +92,7 @@ public void onError(@NonNull Throwable error) { } @Override - public void fetch(@NonNull Property property, @NonNull CoroutineCallback callback) { + public void fetch(@NonNull FetchRequest property, @NonNull CoroutineCallback callback) { if (dataBrokerConnection == null) { return; } @@ -101,72 +102,59 @@ public void fetch(@NonNull Property property, @NonNull CoroutineCallback void fetch( - @NonNull T vssNode, + @NonNull VssNodeFetchRequest request, @NonNull CoroutineCallback callback ) { if (dataBrokerConnection == null) { return; } - dataBrokerConnection.fetch(vssNode, callback); + dataBrokerConnection.fetch(request, callback); } @Override public void update( - @NonNull Property property, - @NonNull Datapoint datapoint, + @NonNull UpdateRequest request, @NonNull CoroutineCallback callback ) { if (dataBrokerConnection == null) { return; } - dataBrokerConnection.update(property, datapoint, callback); + dataBrokerConnection.update(request, callback); } @Override - public void subscribe(@NonNull Property property, @NonNull PropertyListener propertyListener) { + public void subscribe(@NonNull SubscribeRequest request, @NonNull PropertyListener propertyListener) { if (dataBrokerConnection == null) { return; } - dataBrokerConnection.subscribe(property, propertyListener); + dataBrokerConnection.subscribe(request, propertyListener); } @Override public void subscribe( - @NonNull T vssNode, + @NonNull VssNodeSubscribeRequest request, @NonNull VssNodeListener vssNodeListener ) { if (dataBrokerConnection == null) { return; } - ArrayList fields = new ArrayList<>() { - { - add(Types.Field.FIELD_VALUE); - } - }; - - dataBrokerConnection.subscribe(vssNode, fields, vssNodeListener); + dataBrokerConnection.subscribe(request, vssNodeListener); } @Override public void unsubscribe( - @NonNull T vssNode, + @NonNull VssNodeSubscribeRequest request, @NonNull VssNodeListener vssNodeListener ) { if (dataBrokerConnection == null) { return; } - ArrayList fields = new ArrayList<>() { - { - add(Types.Field.FIELD_VALUE); - } - }; - - dataBrokerConnection.unsubscribe(vssNode, fields, vssNodeListener); + dataBrokerConnection.unsubscribe(request, vssNodeListener); } public void disconnect() { @@ -206,9 +194,9 @@ public void unregisterDisconnectListener(@NonNull DisconnectListener listener) { } @Override - public void unsubscribe(@NonNull Property property, @NonNull PropertyListener propertyListener) { + public void unsubscribe(@NonNull SubscribeRequest request, @NonNull PropertyListener propertyListener) { if (dataBrokerConnection != null) { - dataBrokerConnection.unsubscribe(property, propertyListener); + dataBrokerConnection.unsubscribe(request, propertyListener); } } } diff --git a/app/src/main/kotlin/org/eclipse/kuksa/testapp/KuksaDataBrokerActivity.kt b/app/src/main/kotlin/org/eclipse/kuksa/testapp/KuksaDataBrokerActivity.kt index ac222c21..bfe65513 100644 --- a/app/src/main/kotlin/org/eclipse/kuksa/testapp/KuksaDataBrokerActivity.kt +++ b/app/src/main/kotlin/org/eclipse/kuksa/testapp/KuksaDataBrokerActivity.kt @@ -33,10 +33,14 @@ import org.eclipse.kuksa.connectivity.databroker.DataBrokerConnection import org.eclipse.kuksa.connectivity.databroker.listener.DisconnectListener import org.eclipse.kuksa.connectivity.databroker.listener.PropertyListener import org.eclipse.kuksa.connectivity.databroker.listener.VssNodeListener +import org.eclipse.kuksa.connectivity.databroker.request.FetchRequest +import org.eclipse.kuksa.connectivity.databroker.request.SubscribeRequest +import org.eclipse.kuksa.connectivity.databroker.request.UpdateRequest +import org.eclipse.kuksa.connectivity.databroker.request.VssNodeFetchRequest +import org.eclipse.kuksa.connectivity.databroker.request.VssNodeSubscribeRequest import org.eclipse.kuksa.coroutine.CoroutineCallback import org.eclipse.kuksa.extension.entriesMetadata import org.eclipse.kuksa.extension.valueType -import org.eclipse.kuksa.model.Property import org.eclipse.kuksa.proto.v1.KuksaValV1 import org.eclipse.kuksa.proto.v1.KuksaValV1.GetResponse import org.eclipse.kuksa.proto.v1.Types.Datapoint @@ -48,17 +52,20 @@ import org.eclipse.kuksa.testapp.databroker.model.ConnectionInfo import org.eclipse.kuksa.testapp.databroker.view.DataBrokerView import org.eclipse.kuksa.testapp.databroker.viewmodel.ConnectionViewModel import org.eclipse.kuksa.testapp.databroker.viewmodel.ConnectionViewModel.ConnectionViewState +import org.eclipse.kuksa.testapp.databroker.viewmodel.DataBrokerProperty import org.eclipse.kuksa.testapp.databroker.viewmodel.OutputEntry import org.eclipse.kuksa.testapp.databroker.viewmodel.OutputViewModel import org.eclipse.kuksa.testapp.databroker.viewmodel.TopAppBarViewModel -import org.eclipse.kuksa.testapp.databroker.viewmodel.VSSPropertiesViewModel -import org.eclipse.kuksa.testapp.databroker.viewmodel.VssViewModel +import org.eclipse.kuksa.testapp.databroker.viewmodel.VSSPathsViewModel +import org.eclipse.kuksa.testapp.databroker.viewmodel.VssNodesViewModel import org.eclipse.kuksa.testapp.extension.TAG import org.eclipse.kuksa.testapp.preferences.ConnectionInfoRepository import org.eclipse.kuksa.testapp.ui.theme.KuksaAppAndroidTheme +import org.eclipse.kuksa.vss.VssVehicle import org.eclipse.kuksa.vsscore.annotation.VssModelGenerator import org.eclipse.kuksa.vsscore.model.VssNode +@Suppress("performance:SpreadOperator") // API convenience > performance @VssModelGenerator class KuksaDataBrokerActivity : ComponentActivity() { private lateinit var connectionInfoRepository: ConnectionInfoRepository @@ -67,8 +74,8 @@ class KuksaDataBrokerActivity : ComponentActivity() { private val connectionViewModel: ConnectionViewModel by viewModels { ConnectionViewModel.Factory(connectionInfoRepository) } - private val vssPropertiesViewModel: VSSPropertiesViewModel by viewModels() - private val vssViewModel: VssViewModel by viewModels() + private val vssPathsViewModel: VSSPathsViewModel by viewModels() + private val vssNodesViewModel: VssNodesViewModel by viewModels() private val outputViewModel: OutputViewModel by viewModels() private val dataBrokerConnectionCallback = object : CoroutineCallback() { @@ -128,6 +135,43 @@ class KuksaDataBrokerActivity : ComponentActivity() { } override fun onCreate(savedInstanceState: Bundle?) { + fun addVssPathsListeners() { + vssPathsViewModel.onGetProperty = { property: DataBrokerProperty -> + fetchPropertyFieldType(property) + fetchProperty(property) + } + + vssPathsViewModel.onSetProperty = { property: DataBrokerProperty, datapoint: Datapoint -> + updateProperty(property, datapoint) + } + + vssPathsViewModel.onSubscribeProperty = { property: DataBrokerProperty -> + val request = SubscribeRequest(property.vssPath, *property.fieldTypes.toTypedArray()) + dataBrokerEngine.subscribe(request, propertyListener) + } + + vssPathsViewModel.onUnsubscribeProperty = { property: DataBrokerProperty -> + val request = SubscribeRequest(property.vssPath, *property.fieldTypes.toTypedArray()) + dataBrokerEngine.unsubscribe(request, propertyListener) + } + } + + fun addVssNodesListeners() { + vssNodesViewModel.onSubscribeNode = { vssNode -> + val request = VssNodeSubscribeRequest(vssNode) + dataBrokerEngine.subscribe(request, vssNodeListener) + } + + vssNodesViewModel.onUnsubscribeNode = { vssNode -> + val request = VssNodeSubscribeRequest(vssNode) + dataBrokerEngine.unsubscribe(request, vssNodeListener) + } + + vssNodesViewModel.onGetNode = { vssNode -> + fetchVssNode(vssNode) + } + } + super.onCreate(savedInstanceState) Log.d(TAG, "onCreate() called with: savedInstanceState = $savedInstanceState") @@ -139,8 +183,8 @@ class KuksaDataBrokerActivity : ComponentActivity() { DataBrokerView( topAppBarViewModel, connectionViewModel, - vssPropertiesViewModel, - vssViewModel, + vssPathsViewModel, + vssNodesViewModel, outputViewModel, ) } @@ -169,34 +213,8 @@ class KuksaDataBrokerActivity : ComponentActivity() { disconnect() } - vssPropertiesViewModel.onGetProperty = { property: Property -> - fetchPropertyFieldType(property) - fetchProperty(property) - } - - vssPropertiesViewModel.onSetProperty = { property: Property, datapoint: Datapoint -> - updateProperty(property, datapoint) - } - - vssPropertiesViewModel.onSubscribeProperty = { property: Property -> - dataBrokerEngine.subscribe(property, propertyListener) - } - - vssPropertiesViewModel.onUnsubscribeProperty = { property: Property -> - dataBrokerEngine.unsubscribe(property, propertyListener) - } - - vssViewModel.onSubscribeNode = { vssNode -> - dataBrokerEngine.subscribe(vssNode, vssNodeListener) - } - - vssViewModel.onUnsubscribeNode = { vssNode -> - dataBrokerEngine.unsubscribe(vssNode, vssNodeListener) - } - - vssViewModel.onGetNode = { vssNode -> - fetchVssNode(vssNode) - } + addVssPathsListeners() + addVssNodesListeners() } override fun onDestroy() { @@ -221,11 +239,11 @@ class KuksaDataBrokerActivity : ComponentActivity() { dataBrokerEngine.unregisterDisconnectListener(onDisconnectListener) } - private fun fetchPropertyFieldType(property: Property) { - val propertyWithMetaData = property.copy(fields = listOf(Field.FIELD_METADATA)) + private fun fetchPropertyFieldType(property: DataBrokerProperty) { + val request = FetchRequest(property.vssPath, Field.FIELD_METADATA) dataBrokerEngine.fetch( - propertyWithMetaData, + request, object : CoroutineCallback() { override fun onSuccess(result: GetResponse?) { val entriesMetadata = result?.entriesMetadata ?: emptyList() @@ -237,9 +255,9 @@ class KuksaDataBrokerActivity : ComponentActivity() { Log.d(TAG, "Fetched automatic value type from meta data: $automaticValueType") - val vssProperties = vssPropertiesViewModel.vssProperties + val vssProperties = vssPathsViewModel.dataBrokerProperty .copy(valueType = automaticValueType) - vssPropertiesViewModel.updateVssProperties(vssProperties) + vssPathsViewModel.updateDataBrokerProperty(vssProperties) } override fun onError(error: Throwable) { @@ -249,11 +267,13 @@ class KuksaDataBrokerActivity : ComponentActivity() { ) } - private fun fetchProperty(property: Property) { + private fun fetchProperty(property: DataBrokerProperty) { Log.d(TAG, "Fetch property: $property") + val request = FetchRequest(property.vssPath, *property.fieldTypes.toTypedArray()) + dataBrokerEngine.fetch( - property, + request, object : CoroutineCallback() { override fun onSuccess(result: GetResponse?) { val errorsList = result?.errorsList @@ -280,12 +300,12 @@ class KuksaDataBrokerActivity : ComponentActivity() { ) } - private fun updateProperty(property: Property, datapoint: Datapoint) { + private fun updateProperty(property: DataBrokerProperty, datapoint: Datapoint) { Log.d(TAG, "Update property: $property dataPoint: $datapoint, type: ${datapoint.valueCase}") + val request = UpdateRequest(property.vssPath, datapoint, *property.fieldTypes.toTypedArray()) dataBrokerEngine.update( - property, - datapoint, + request, object : CoroutineCallback() { override fun onSuccess(result: KuksaValV1.SetResponse?) { val errorsList = result?.errorsList @@ -305,8 +325,9 @@ class KuksaDataBrokerActivity : ComponentActivity() { } private fun fetchVssNode(vssNode: VssNode) { + val request = VssNodeFetchRequest(vssNode) dataBrokerEngine.fetch( - vssNode, + request, object : CoroutineCallback() { override fun onSuccess(result: VssNode?) { Log.d(TAG, "Fetched node: $result") @@ -321,7 +342,7 @@ class KuksaDataBrokerActivity : ComponentActivity() { } private fun loadVssPathSuggestions() { - val property = Property("Vehicle", listOf(Field.FIELD_VALUE)) + val property = FetchRequest(VssVehicle().vssPath, Field.FIELD_VALUE) dataBrokerEngine.fetch( property, @@ -330,7 +351,7 @@ class KuksaDataBrokerActivity : ComponentActivity() { val entriesList = result?.entriesList val vssPaths = entriesList?.map { it.path } ?: emptyList() - vssPropertiesViewModel.updateSuggestions(vssPaths) + vssPathsViewModel.updateSuggestions(vssPaths) } override fun onError(error: Throwable) { diff --git a/app/src/main/kotlin/org/eclipse/kuksa/testapp/databroker/DataBrokerEngine.kt b/app/src/main/kotlin/org/eclipse/kuksa/testapp/databroker/DataBrokerEngine.kt index 414fe752..67c0b06d 100644 --- a/app/src/main/kotlin/org/eclipse/kuksa/testapp/databroker/DataBrokerEngine.kt +++ b/app/src/main/kotlin/org/eclipse/kuksa/testapp/databroker/DataBrokerEngine.kt @@ -24,11 +24,14 @@ import org.eclipse.kuksa.connectivity.databroker.DataBrokerConnection import org.eclipse.kuksa.connectivity.databroker.listener.DisconnectListener import org.eclipse.kuksa.connectivity.databroker.listener.PropertyListener import org.eclipse.kuksa.connectivity.databroker.listener.VssNodeListener +import org.eclipse.kuksa.connectivity.databroker.request.FetchRequest +import org.eclipse.kuksa.connectivity.databroker.request.SubscribeRequest +import org.eclipse.kuksa.connectivity.databroker.request.UpdateRequest +import org.eclipse.kuksa.connectivity.databroker.request.VssNodeFetchRequest +import org.eclipse.kuksa.connectivity.databroker.request.VssNodeSubscribeRequest import org.eclipse.kuksa.coroutine.CoroutineCallback -import org.eclipse.kuksa.model.Property import org.eclipse.kuksa.proto.v1.KuksaValV1.GetResponse import org.eclipse.kuksa.proto.v1.KuksaValV1.SetResponse -import org.eclipse.kuksa.proto.v1.Types.Datapoint import org.eclipse.kuksa.testapp.databroker.model.ConnectionInfo import org.eclipse.kuksa.vsscore.model.VssNode @@ -43,29 +46,28 @@ interface DataBrokerEngine { ) fun fetch( - property: Property, + request: FetchRequest, callback: CoroutineCallback, ) - fun fetch(vssNode: T, callback: CoroutineCallback) + fun fetch(request: VssNodeFetchRequest, callback: CoroutineCallback) fun update( - property: Property, - datapoint: Datapoint, + request: UpdateRequest, callback: CoroutineCallback, ) - fun subscribe(property: Property, propertyListener: PropertyListener) + fun subscribe(request: SubscribeRequest, propertyListener: PropertyListener) - fun unsubscribe(property: Property, propertyListener: PropertyListener) + fun unsubscribe(request: SubscribeRequest, propertyListener: PropertyListener) fun subscribe( - vssNode: T, + request: VssNodeSubscribeRequest, vssNodeListener: VssNodeListener, ) fun unsubscribe( - vssNode: T, + request: VssNodeSubscribeRequest, vssNodeListener: VssNodeListener, ) diff --git a/app/src/main/kotlin/org/eclipse/kuksa/testapp/databroker/KotlinDataBrokerEngine.kt b/app/src/main/kotlin/org/eclipse/kuksa/testapp/databroker/KotlinDataBrokerEngine.kt index f6f6ef5c..31f4298a 100644 --- a/app/src/main/kotlin/org/eclipse/kuksa/testapp/databroker/KotlinDataBrokerEngine.kt +++ b/app/src/main/kotlin/org/eclipse/kuksa/testapp/databroker/KotlinDataBrokerEngine.kt @@ -28,11 +28,14 @@ import org.eclipse.kuksa.connectivity.databroker.DataBrokerException import org.eclipse.kuksa.connectivity.databroker.listener.DisconnectListener import org.eclipse.kuksa.connectivity.databroker.listener.PropertyListener import org.eclipse.kuksa.connectivity.databroker.listener.VssNodeListener +import org.eclipse.kuksa.connectivity.databroker.request.FetchRequest +import org.eclipse.kuksa.connectivity.databroker.request.SubscribeRequest +import org.eclipse.kuksa.connectivity.databroker.request.UpdateRequest +import org.eclipse.kuksa.connectivity.databroker.request.VssNodeFetchRequest +import org.eclipse.kuksa.connectivity.databroker.request.VssNodeSubscribeRequest import org.eclipse.kuksa.coroutine.CoroutineCallback -import org.eclipse.kuksa.model.Property import org.eclipse.kuksa.proto.v1.KuksaValV1.GetResponse import org.eclipse.kuksa.proto.v1.KuksaValV1.SetResponse -import org.eclipse.kuksa.proto.v1.Types.Datapoint import org.eclipse.kuksa.testapp.databroker.connection.DataBrokerConnectorFactory import org.eclipse.kuksa.testapp.databroker.model.ConnectionInfo import org.eclipse.kuksa.vsscore.model.VssNode @@ -74,10 +77,10 @@ class KotlinDataBrokerEngine( } } - override fun fetch(property: Property, callback: CoroutineCallback) { + override fun fetch(request: FetchRequest, callback: CoroutineCallback) { lifecycleScope.launch { try { - val response = dataBrokerConnection?.fetch(property) ?: return@launch + val response = dataBrokerConnection?.fetch(request) ?: return@launch callback.onSuccess(response) } catch (e: DataBrokerException) { callback.onError(e) @@ -85,10 +88,10 @@ class KotlinDataBrokerEngine( } } - override fun fetch(vssNode: T, callback: CoroutineCallback) { + override fun fetch(request: VssNodeFetchRequest, callback: CoroutineCallback) { lifecycleScope.launch { try { - val response = dataBrokerConnection?.fetch(vssNode) ?: return@launch + val response = dataBrokerConnection?.fetch(request) ?: return@launch callback.onSuccess(response) } catch (e: DataBrokerException) { callback.onError(e) @@ -96,10 +99,10 @@ class KotlinDataBrokerEngine( } } - override fun update(property: Property, datapoint: Datapoint, callback: CoroutineCallback) { + override fun update(request: UpdateRequest, callback: CoroutineCallback) { lifecycleScope.launch { try { - val response = dataBrokerConnection?.update(property, datapoint) ?: return@launch + val response = dataBrokerConnection?.update(request) ?: return@launch callback.onSuccess(response) } catch (e: DataBrokerException) { callback.onError(e) @@ -107,28 +110,28 @@ class KotlinDataBrokerEngine( } } - override fun subscribe(property: Property, propertyListener: PropertyListener) { - dataBrokerConnection?.subscribe(property, propertyListener) + override fun subscribe(request: SubscribeRequest, propertyListener: PropertyListener) { + dataBrokerConnection?.subscribe(request, propertyListener) } - override fun unsubscribe(property: Property, propertyListener: PropertyListener) { - dataBrokerConnection?.unsubscribe(property, propertyListener) + override fun unsubscribe(request: SubscribeRequest, propertyListener: PropertyListener) { + dataBrokerConnection?.unsubscribe(request, propertyListener) } override fun subscribe( - vssNode: T, + request: VssNodeSubscribeRequest, vssNodeListener: VssNodeListener, ) { lifecycleScope.launch { - dataBrokerConnection?.subscribe(vssNode, listener = vssNodeListener) + dataBrokerConnection?.subscribe(request, listener = vssNodeListener) } } override fun unsubscribe( - vssNode: T, + request: VssNodeSubscribeRequest, vssNodeListener: VssNodeListener, ) { - dataBrokerConnection?.unsubscribe(vssNode, listener = vssNodeListener) + dataBrokerConnection?.unsubscribe(request, listener = vssNodeListener) } override fun disconnect() { diff --git a/app/src/main/kotlin/org/eclipse/kuksa/testapp/databroker/view/DataBrokerView.kt b/app/src/main/kotlin/org/eclipse/kuksa/testapp/databroker/view/DataBrokerView.kt index c4799115..6bfc2476 100644 --- a/app/src/main/kotlin/org/eclipse/kuksa/testapp/databroker/view/DataBrokerView.kt +++ b/app/src/main/kotlin/org/eclipse/kuksa/testapp/databroker/view/DataBrokerView.kt @@ -82,8 +82,8 @@ import org.eclipse.kuksa.testapp.databroker.viewmodel.ConnectionViewModel import org.eclipse.kuksa.testapp.databroker.viewmodel.OutputViewModel import org.eclipse.kuksa.testapp.databroker.viewmodel.TopAppBarViewModel import org.eclipse.kuksa.testapp.databroker.viewmodel.TopAppBarViewModel.DataBrokerMode -import org.eclipse.kuksa.testapp.databroker.viewmodel.VSSPropertiesViewModel -import org.eclipse.kuksa.testapp.databroker.viewmodel.VssViewModel +import org.eclipse.kuksa.testapp.databroker.viewmodel.VSSPathsViewModel +import org.eclipse.kuksa.testapp.databroker.viewmodel.VssNodesViewModel import org.eclipse.kuksa.testapp.extension.compose.Headline import org.eclipse.kuksa.testapp.extension.compose.OverflowMenu import org.eclipse.kuksa.testapp.extension.compose.SimpleExposedDropdownMenuBox @@ -102,8 +102,8 @@ val MinimumButtonWidth = 150.dp fun DataBrokerView( topAppBarViewModel: TopAppBarViewModel, connectionViewModel: ConnectionViewModel, - vssPropertiesViewModel: VSSPropertiesViewModel, - vssViewModel: VssViewModel, + vssPropertiesViewModel: VSSPathsViewModel, + vssNodesViewModel: VssNodesViewModel, outputViewModel: OutputViewModel, ) { Scaffold( @@ -126,7 +126,7 @@ fun DataBrokerView( if (connectionViewModel.isConnected) { when (dataBrokerMode) { DataBrokerMode.VSS_PATH -> DataBrokerProperties(vssPropertiesViewModel) - DataBrokerMode.VSS_FILE -> DataBrokerVssNodes(vssViewModel) + DataBrokerMode.VSS_FILE -> DataBrokerVssNodes(vssNodesViewModel) } } Spacer(modifier = Modifier.padding(top = DefaultElementPadding)) @@ -233,9 +233,9 @@ private fun ConnectionStatusIcon( } @Composable -fun DataBrokerVssNodes(viewModel: VssViewModel) { +fun DataBrokerVssNodes(viewModel: VssNodesViewModel) { Column { - Headline(name = "VSS Nodes") + Headline(name = "Generated VSS Nodes") val adapter = object : SuggestionAdapter { override fun toString(item: VssNode): String { @@ -288,21 +288,21 @@ fun DataBrokerVssNodes(viewModel: VssViewModel) { } @Composable -fun DataBrokerProperties(viewModel: VSSPropertiesViewModel) { - val vssProperties = viewModel.vssProperties +fun DataBrokerProperties(viewModel: VSSPathsViewModel) { + val dataBrokerProperty = viewModel.dataBrokerProperty var expanded by remember { mutableStateOf(false) } Column { - Headline(name = "Properties") + Headline(name = "VSS Paths") SuggestionTextView( suggestions = viewModel.suggestions, - value = viewModel.vssProperties.vssPath, + value = dataBrokerProperty.vssPath, onValueChanged = { - val newVssProperties = viewModel.vssProperties.copy( + val newVssProperties = dataBrokerProperty.copy( vssPath = it, valueType = ValueCase.VALUE_NOT_SET, ) - viewModel.updateVssProperties(newVssProperties) + viewModel.updateDataBrokerProperty(newVssProperties) }, label = { Text(text = "VSS Path") @@ -315,10 +315,10 @@ fun DataBrokerProperties(viewModel: VSSPropertiesViewModel) { Spacer(modifier = Modifier.padding(top = DefaultElementPadding)) Row { TextField( - value = "${viewModel.vssProperties.valueType}", + value = "${dataBrokerProperty.valueType}", onValueChange = {}, label = { - Text("Field Type") + Text("Value Type") }, readOnly = true, enabled = false, @@ -357,8 +357,8 @@ fun DataBrokerProperties(viewModel: VSSPropertiesViewModel) { onClick = { expanded = false - val newVssProperties = viewModel.vssProperties.copy(valueType = it) - viewModel.updateVssProperties(newVssProperties) + val newVssProperties = dataBrokerProperty.copy(valueType = it) + viewModel.updateDataBrokerProperty(newVssProperties) }, ) } @@ -368,10 +368,10 @@ fun DataBrokerProperties(viewModel: VSSPropertiesViewModel) { Spacer(modifier = Modifier.padding(top = DefaultElementPadding)) Row { TextField( - value = vssProperties.value, + value = dataBrokerProperty.value, onValueChange = { - val newVssProperties = viewModel.vssProperties.copy(value = it) - viewModel.updateVssProperties(newVssProperties) + val newVssProperties = dataBrokerProperty.copy(value = it) + viewModel.updateDataBrokerProperty(newVssProperties) }, modifier = Modifier .padding(start = DefaultEdgePadding) @@ -389,8 +389,8 @@ fun DataBrokerProperties(viewModel: VSSPropertiesViewModel) { label = "Field Type", list = viewModel.fieldTypes, onValueChange = { - val newVssProperties = viewModel.vssProperties.copy(fieldType = it) - viewModel.updateVssProperties(newVssProperties) + val newVssProperties = dataBrokerProperty.copy(fieldTypes = setOf(it)) + viewModel.updateDataBrokerProperty(newVssProperties) }, ) } @@ -401,16 +401,16 @@ fun DataBrokerProperties(viewModel: VSSPropertiesViewModel) { ) { Button( onClick = { - viewModel.onGetProperty(viewModel.property) + viewModel.onGetProperty(dataBrokerProperty) }, modifier = Modifier.requiredWidth(80.dp), ) { Text(text = "Get") } Button( - enabled = viewModel.vssProperties.valueType != ValueCase.VALUE_NOT_SET, + enabled = dataBrokerProperty.valueType != ValueCase.VALUE_NOT_SET, onClick = { - viewModel.onSetProperty(viewModel.property, viewModel.datapoint) + viewModel.onSetProperty(dataBrokerProperty, viewModel.datapoint) }, modifier = Modifier.requiredWidth(80.dp), ) { @@ -418,15 +418,15 @@ fun DataBrokerProperties(viewModel: VSSPropertiesViewModel) { } if (viewModel.isSubscribed) { Button(onClick = { - viewModel.subscribedProperties.remove(viewModel.property) - viewModel.onUnsubscribeProperty(viewModel.property) + viewModel.subscribedProperties.remove(dataBrokerProperty) + viewModel.onUnsubscribeProperty(dataBrokerProperty) }) { Text(text = "Unsubscribe") } } else { Button(onClick = { - viewModel.subscribedProperties.add(viewModel.property) - viewModel.onSubscribeProperty(viewModel.property) + viewModel.subscribedProperties.add(dataBrokerProperty) + viewModel.onSubscribeProperty(dataBrokerProperty) }) { Text(text = "Subscribe") } @@ -498,8 +498,8 @@ fun Preview() { DataBrokerView( TopAppBarViewModel(), ConnectionViewModel(connectionInfoRepository), - VSSPropertiesViewModel(), - VssViewModel(), + VSSPathsViewModel(), + VssNodesViewModel(), OutputViewModel(), ) } diff --git a/app/src/main/kotlin/org/eclipse/kuksa/testapp/databroker/viewmodel/VssViewModel.kt b/app/src/main/kotlin/org/eclipse/kuksa/testapp/databroker/viewmodel/VssNodesViewModel.kt similarity index 97% rename from app/src/main/kotlin/org/eclipse/kuksa/testapp/databroker/viewmodel/VssViewModel.kt rename to app/src/main/kotlin/org/eclipse/kuksa/testapp/databroker/viewmodel/VssNodesViewModel.kt index 121bea0f..1f1cb3da 100644 --- a/app/src/main/kotlin/org/eclipse/kuksa/testapp/databroker/viewmodel/VssViewModel.kt +++ b/app/src/main/kotlin/org/eclipse/kuksa/testapp/databroker/viewmodel/VssNodesViewModel.kt @@ -29,7 +29,7 @@ import org.eclipse.kuksa.vss.VssVehicle import org.eclipse.kuksa.vsscore.model.VssNode import org.eclipse.kuksa.vsscore.model.heritage -class VssViewModel : ViewModel() { +class VssNodesViewModel : ViewModel() { var onGetNode: (node: VssNode) -> Unit = { } var onSubscribeNode: (node: VssNode) -> Unit = { } var onUnsubscribeNode: (node: VssNode) -> Unit = { } diff --git a/app/src/main/kotlin/org/eclipse/kuksa/testapp/databroker/viewmodel/VssPropertiesViewModel.kt b/app/src/main/kotlin/org/eclipse/kuksa/testapp/databroker/viewmodel/VssPropertiesViewModel.kt index 0ba78623..68479304 100644 --- a/app/src/main/kotlin/org/eclipse/kuksa/testapp/databroker/viewmodel/VssPropertiesViewModel.kt +++ b/app/src/main/kotlin/org/eclipse/kuksa/testapp/databroker/viewmodel/VssPropertiesViewModel.kt @@ -27,25 +27,28 @@ import androidx.compose.runtime.mutableStateOf import androidx.compose.runtime.setValue import androidx.lifecycle.ViewModel import org.eclipse.kuksa.extension.createDatapoint -import org.eclipse.kuksa.model.Property import org.eclipse.kuksa.proto.v1.Types.Datapoint import org.eclipse.kuksa.proto.v1.Types.Datapoint.ValueCase import org.eclipse.kuksa.proto.v1.Types.Field import java.util.TreeSet -class VSSPropertiesViewModel : ViewModel() { - var onGetProperty: (property: Property) -> Unit = { } - var onSetProperty: (property: Property, datapoint: Datapoint) -> Unit = { _: Property, _: Datapoint -> } - var onSubscribeProperty: (property: Property) -> Unit = { } - var onUnsubscribeProperty: (property: Property) -> Unit = { } +class VSSPathsViewModel : ViewModel() { + var onGetProperty: (property: DataBrokerProperty) -> Unit = { } + var onSetProperty: (property: DataBrokerProperty, datapoint: Datapoint) -> Unit = { + _: DataBrokerProperty, + _: Datapoint, + -> + } + var onSubscribeProperty: (property: DataBrokerProperty) -> Unit = { } + var onUnsubscribeProperty: (property: DataBrokerProperty) -> Unit = { } - var subscribedProperties = mutableStateListOf() + var subscribedProperties = mutableStateListOf() val isSubscribed by derivedStateOf { - subscribedProperties.contains(property) + subscribedProperties.contains(dataBrokerProperty) } - var vssProperties: VSSProperties by mutableStateOf(VSSProperties()) + var dataBrokerProperty: DataBrokerProperty by mutableStateOf(DataBrokerProperty()) private set val valueTypes: List = ValueCase.entries @@ -59,13 +62,10 @@ class VSSPropertiesViewModel : ViewModel() { private set val datapoint: Datapoint - get() = vssProperties.valueType.createDatapoint(vssProperties.value) - - val property: Property - get() = Property(vssProperties.vssPath, listOf(vssProperties.fieldType)) + get() = dataBrokerProperty.valueType.createDatapoint(dataBrokerProperty.value) - fun updateVssProperties(vssProperties: VSSProperties = VSSProperties()) { - this.vssProperties = vssProperties + fun updateDataBrokerProperty(property: DataBrokerProperty = DataBrokerProperty()) { + dataBrokerProperty = property } fun updateSuggestions(vssPaths: Collection) { @@ -90,9 +90,9 @@ class VSSPropertiesViewModel : ViewModel() { } @Immutable -data class VSSProperties( +data class DataBrokerProperty( val vssPath: String = "Vehicle", val valueType: ValueCase = ValueCase.VALUE_NOT_SET, val value: String = "", - val fieldType: Field = Field.FIELD_VALUE, + val fieldTypes: Collection = setOf(Field.FIELD_VALUE), ) diff --git a/docs/QUICKSTART.md b/docs/QUICKSTART.md index 3ad3c699..4d627edc 100644 --- a/docs/QUICKSTART.md +++ b/docs/QUICKSTART.md @@ -68,8 +68,8 @@ void connectInsecure(String host, int port) { ```kotlin fun fetch() { lifecycleScope.launch { - val property = Property("Vehicle.Speed", listOf(Field.FIELD_VALUE)) - val response = dataBrokerConnection?.fetch(property) ?: return@launch + val request = FetchRequest("Vehicle.Speed", setOf(Field.FIELD_VALUE)) + val response = dataBrokerConnection?.fetch(request) ?: return@launch val entry = response.entriesList.first() // Don't forget to handle empty responses val value = entry.value val speed = value.float @@ -78,14 +78,14 @@ fun fetch() { fun update() { lifecycleScope.launch { - val property = Property("Vehicle.Speed", listOf(Field.FIELD_VALUE)) + val request = UpdateRequest("Vehicle.Speed", setOf(Field.FIELD_VALUE)) val datapoint = Datapoint.newBuilder().setFloat(100f).build() dataBrokerConnection?.update(property, datapoint) } } fun subscribe() { - val property = Property("Vehicle.Speed", listOf(Field.FIELD_VALUE)) + val request = SubscribeRequest("Vehicle.Speed", setOf(Field.FIELD_VALUE)) val propertyListener = object : PropertyListener { override fun onPropertyChanged(entryUpdates: List) { entryUpdates.forEach { entryUpdate -> @@ -100,14 +100,14 @@ fun subscribe() { } } - dataBrokerConnection?.subscribe(property, propertyListener) + dataBrokerConnection?.subscribe(request, propertyListener) } ``` *Java* ```java void fetch() { - Property property = new Property("Vehicle.Speed", Collections.singleton(Types.Field.FIELD_VALUE)); - dataBrokerConnection.fetch(property, new CoroutineCallback() { + FetchRequest request = new FetchRequest("Vehicle.Speed", Collections.singleton(Types.Field.FIELD_VALUE)); + dataBrokerConnection.fetch(request, new CoroutineCallback() { @Override public void onSuccess(GetResponse result) { result.entriesList.first() // Don't forget to handle empty responses @@ -119,19 +119,19 @@ void fetch() { } void update() { - Property property = new Property("Vehicle.Speed", Collections.singleton(Types.Field.FIELD_VALUE)); Datapoint datapoint = Datapoint.newBuilder().setFloat(100f).build(); - dataBrokerConnection.update(property, datapoint, new CoroutineCallback() { + UpdateRequest request = new UpdateRequest("Vehicle.Speed", datapoint, Collections.singleton(Types.Field.FIELD_VALUE)); + dataBrokerConnection.update(request, new CoroutineCallback() { @Override public void onSuccess(KuksaValV1.SetResponse result) { - // handle result + // handle result } }); } void subscribe() { - Property property = new Property("Vehicle.Speed", Collections.singleton(Types.Field.FIELD_VALUE)); - dataBrokerConnection.subscribe(property, new PropertyListener() { + SubscribeRequest request = new SubscribeRequest("Vehicle.Speed", Collections.singleton(Types.Field.FIELD_VALUE)); + dataBrokerConnection.subscribe(request, new PropertyListener() { @Override public void onPropertyChanged(@NonNull List entryUpdates) { for (KuksaValV1.EntryUpdate entryUpdate : entryUpdates) { @@ -163,7 +163,7 @@ of the same specification the Databroker uses. For starters you can retrieve an release page of the [COVESA Vehicle Signal Specification GitHub repository](https://github.com/COVESA/vehicle_signal_specification/releases). *app/build.gradle.kts* -``` +```kotlin plugins { id("org.eclipse.kuksa.vss-processor-plugin") } @@ -188,7 +188,7 @@ convenience operators and extension methods to work with to manipulate the tree class Activity ``` > [!IMPORTANT] -> Keep in mind to always synchronize the VSS file between the client and the Databroker. +> Keep in mind to always synchronize a compatible (e.g. subset) VSS file between the client and the Databroker. *Example .yaml VSS file* @@ -237,7 +237,8 @@ data class VssSpeed @JvmOverloads constructor( fun fetch() { lifecycleScope.launch { val vssSpeed = VssVehicle.VssSpeed() - val updatedSpeed = dataBrokerConnection?.fetch(vssSpeed) + val request = VssNodeFetchRequest(vssSpeed) + val updatedSpeed = dataBrokerConnection?.fetch(request) val speed = updatedSpeed?.value } } @@ -245,13 +246,15 @@ fun fetch() { fun update() { lifecycleScope.launch { val vssSpeed = VssVehicle.VssSpeed(value = 100f) - dataBrokerConnection?.update(vssSpeed) + val request = VssNodeUpdateRequest(vssSpeed) + dataBrokerConnection?.update(request) } } fun subscribe() { val vssSpeed = VssVehicle.VssSpeed(value = 100f) - dataBrokerConnection?.subscribe(vssSpeed, listener = object : VssNodeListener { + val request = VssNodeSubscribeRequest(vssSpeed) + dataBrokerConnection?.subscribe(request, listener = object : VssNodeListener { override fun onNodeChanged(vssNode: VssVehicle.VssSpeed) { val speed = vssSpeed.value } @@ -266,9 +269,9 @@ fun subscribe() { ```java void fetch() { VssVehicle.VssSpeed vssSpeed = new VssVehicle.VssSpeed(); + VssNodeFetchRequest request = new VssNodeFetchRequest(vssSpeed) dataBrokerConnection.fetch( - vssSpeed, - Collections.singleton(Types.Field.FIELD_VALUE), + request, new CoroutineCallback() { @Override public void onSuccess(@Nullable VssVehicle.VssSpeed result) { @@ -285,9 +288,9 @@ void fetch() { void update() { VssVehicle.VssSpeed vssSpeed = new VssVehicle.VssSpeed(100f); + VssNodeUpdateRequest request = new VssNodeUpdateRequest(vssSpeed) dataBrokerConnection.update( - vssSpeed, - Collections.singleton(Types.Field.FIELD_VALUE), + request, new CoroutineCallback>() { @Override public void onSuccess(@Nullable Collection result) { @@ -304,9 +307,9 @@ void update() { void subscribe() { VssVehicle.VssSpeed vssSpeed = new VssVehicle.VssSpeed(); + VssNodeSubscribeRequest request = new VssNodeSubscribeRequest(vssSpeed) dataBrokerConnection.subscribe( - vssSpeed, - Collections.singleton(Types.Field.FIELD_VALUE), + request, new VssNodeListener() { @Override public void onNodeChanged(@NonNull VssVehicle.VssSpeed vssNode) { diff --git a/kuksa-sdk/src/main/kotlin/org/eclipse/kuksa/connectivity/databroker/DataBrokerConnection.kt b/kuksa-sdk/src/main/kotlin/org/eclipse/kuksa/connectivity/databroker/DataBrokerConnection.kt index 9d1638f7..1e451b86 100644 --- a/kuksa-sdk/src/main/kotlin/org/eclipse/kuksa/connectivity/databroker/DataBrokerConnection.kt +++ b/kuksa-sdk/src/main/kotlin/org/eclipse/kuksa/connectivity/databroker/DataBrokerConnection.kt @@ -28,17 +28,21 @@ import org.eclipse.kuksa.connectivity.authentication.JsonWebToken import org.eclipse.kuksa.connectivity.databroker.listener.DisconnectListener import org.eclipse.kuksa.connectivity.databroker.listener.PropertyListener import org.eclipse.kuksa.connectivity.databroker.listener.VssNodeListener +import org.eclipse.kuksa.connectivity.databroker.request.FetchRequest +import org.eclipse.kuksa.connectivity.databroker.request.SubscribeRequest +import org.eclipse.kuksa.connectivity.databroker.request.UpdateRequest +import org.eclipse.kuksa.connectivity.databroker.request.VssNodeFetchRequest +import org.eclipse.kuksa.connectivity.databroker.request.VssNodeSubscribeRequest +import org.eclipse.kuksa.connectivity.databroker.request.VssNodeUpdateRequest import org.eclipse.kuksa.connectivity.databroker.subscription.DataBrokerSubscriber import org.eclipse.kuksa.extension.TAG import org.eclipse.kuksa.extension.datapoint import org.eclipse.kuksa.extension.vss.copy -import org.eclipse.kuksa.model.Property import org.eclipse.kuksa.pattern.listener.MultiListener import org.eclipse.kuksa.proto.v1.KuksaValV1.GetResponse import org.eclipse.kuksa.proto.v1.KuksaValV1.SetResponse import org.eclipse.kuksa.proto.v1.Types import org.eclipse.kuksa.proto.v1.Types.Datapoint -import org.eclipse.kuksa.proto.v1.Types.Field import org.eclipse.kuksa.vsscore.model.VssLeaf import org.eclipse.kuksa.vsscore.model.VssNode import org.eclipse.kuksa.vsscore.model.heritage @@ -49,6 +53,7 @@ import kotlin.properties.Delegates * The DataBrokerConnection holds an active connection to the DataBroker. The Connection can be use to interact with the * DataBroker. */ +@Suppress("performance:SpreadOperator") // API convenience > performance class DataBrokerConnection internal constructor( private val managedChannel: ManagedChannel, private val dispatcher: CoroutineDispatcher = Dispatchers.Default, @@ -86,29 +91,29 @@ class DataBrokerConnection internal constructor( } /** - * Subscribes to the specified [property] and notifies the provided [propertyListener] about updates. + * Subscribes to the specified [request] and notifies the provided [propertyListener] about updates. * * Throws a [DataBrokerException] in case the connection to the DataBroker is no longer active */ fun subscribe( - property: Property, + request: SubscribeRequest, propertyListener: PropertyListener, ) { - val vssPath = property.vssPath - property.fields.forEach { field -> + val vssPath = request.vssPath + request.fields.forEach { field -> dataBrokerSubscriber.subscribe(vssPath, field, propertyListener) } } /** - * Unsubscribes the [propertyListener] from updates of the specified [property]. + * Unsubscribes the [propertyListener] from updates of the specified [request]. */ fun unsubscribe( - property: Property, + request: SubscribeRequest, propertyListener: PropertyListener, ) { - val vssPath = property.vssPath - property.fields.forEach { field -> + val vssPath = request.vssPath + request.fields.forEach { field -> dataBrokerSubscriber.unsubscribe(vssPath, field, propertyListener) } } @@ -117,33 +122,35 @@ class DataBrokerConnection internal constructor( * Subscribes to the specified [VssNode] with the provided [VssNodeListener]. Only a [VssLeaf] * can be subscribed because they have an actual value. When provided with any parent [VssNode] then this * [subscribe] method will find all [VssLeaf] children and subscribes them instead. Once subscribed the - * application will be notified about any changes to every subscribed [VssLeaf]. The [fields] can be used to - * subscribe to different information of the [specification]. The default for the [fields] parameter is a list with - * a single [Types.Field.FIELD_VALUE] entry. + * application will be notified about any changes to every subscribed [VssLeaf]. + * The [VssNodeSubscribeRequest.fields] can be used to subscribe to different information of the [VssNode]. + * The default for the [Types.Field] parameter is a list with a single [Types.Field.FIELD_VALUE] entry. * * @throws DataBrokerException in case the connection to the DataBroker is no longer active */ - @JvmOverloads fun subscribe( - specification: T, - fields: Collection = listOf(Field.FIELD_VALUE), + request: VssNodeSubscribeRequest, listener: VssNodeListener, ) { + val fields = request.fields + val vssNode = request.vssNode fields.forEach { field -> - dataBrokerSubscriber.subscribe(specification, field, listener) + dataBrokerSubscriber.subscribe(vssNode, field, listener) } } /** - * Unsubscribes the [listener] from updates of the specified [fields] and [specification]. + * Unsubscribes the [listener] from updates of the specified [VssNodeSubscribeRequest.fields] and + * [VssNodeSubscribeRequest.vssNode]. */ fun unsubscribe( - specification: T, - fields: Collection = listOf(Field.FIELD_VALUE), + request: VssNodeSubscribeRequest, listener: VssNodeListener, ) { + val fields = request.fields + val vssNode = request.vssNode fields.forEach { field -> - dataBrokerSubscriber.unsubscribe(specification, field, listener) + dataBrokerSubscriber.unsubscribe(vssNode, field, listener) } } @@ -152,39 +159,34 @@ class DataBrokerConnection internal constructor( * * @throws DataBrokerException in case the connection to the DataBroker is no longer active */ - suspend fun fetch(property: Property): GetResponse { - Log.d(TAG, "fetchProperty() called with: property: $property") - return dataBrokerTransporter.fetch(property.vssPath, property.fields) + suspend fun fetch(request: FetchRequest): GetResponse { + Log.d(TAG, "fetchProperty() called with: property: $request") + return dataBrokerTransporter.fetch(request.vssPath, *request.fields) } /** * Retrieves the [VssNode] and returns it. The retrieved [VssNode] * is of the same type as the inputted one. All underlying heirs are changed to reflect the data broker state. - * The [fields] can be used to subscribe to different information of the [specification]. The default for the - * [fields] parameter is a list with a single [Types.Field.FIELD_VALUE] entry. * * @throws DataBrokerException in case the connection to the DataBroker is no longer active */ @Suppress("exceptions:TooGenericExceptionCaught") // Handling is bundled together - @JvmOverloads - suspend fun fetch( - specification: T, - fields: Collection = listOf(Field.FIELD_VALUE), - ): T { + suspend fun fetch(request: VssNodeFetchRequest): T { return withContext(dispatcher) { try { - val property = Property(specification.vssPath, fields) - val response = fetch(property) + val vssNode = request.vssNode + val simpleFetchRequest = FetchRequest(request.vssPath, *request.fields) + val response = fetch(simpleFetchRequest) val entries = response.entriesList if (entries.isEmpty()) { Log.w(TAG, "No entries found for fetched specification!") - return@withContext specification + return@withContext vssNode } // Update every heir specification // TODO: Can be optimized to not replace the whole heritage line for every child entry one by one - var updatedSpecification: T = specification + var updatedSpecification: T = vssNode val heritage = updatedSpecification.heritage entries.forEach { entry -> updatedSpecification = updatedSpecification.copy(entry.path, entry.value, heritage) @@ -198,39 +200,33 @@ class DataBrokerConnection internal constructor( } /** - * Updates the underlying property of the specified vssPath with the updatedProperty. Notifies the callback - * about (un)successful operation. + * Updates the underlying data broker property of the specified [UpdateRequest.vssPath] with the + * [UpdateRequest.dataPoint]. Notifies the callback about (un)successful operation. * * @throws DataBrokerException in case the connection to the DataBroker is no longer active */ - suspend fun update( - property: Property, - datapoint: Datapoint, - ): SetResponse { - Log.d(TAG, "updateProperty() called with: updatedProperty = $property") - return dataBrokerTransporter.update(property.vssPath, property.fields, datapoint) + suspend fun update(request: UpdateRequest): SetResponse { + Log.d(TAG, "updateProperty() called with: updatedProperty = $request") + return dataBrokerTransporter.update(request.vssPath, request.dataPoint, *request.fields) } /** * Only a [VssLeaf] can be updated because they have an actual value. When provided with any parent * [VssNode] then this [update] method will find all [VssLeaf] children and updates their corresponding - * [fields] instead. - * Compared to [update] with only one [Property] and [Datapoint], here multiple [SetResponse] will be returned + * [Types.Field] instead. + * Compared to [update] with only one [UpdateRequest], here multiple [SetResponse] will be returned * because a [VssNode] may consists of multiple values which may need to be updated. * * @throws DataBrokerException in case the connection to the DataBroker is no longer active * @throws IllegalArgumentException if the [VssLeaf] could not be converted to a [Datapoint]. */ - @JvmOverloads - suspend fun update( - vssNode: VssNode, - fields: Collection = listOf(Field.FIELD_VALUE), - ): Collection { + suspend fun update(request: VssNodeUpdateRequest): Collection { val responses = mutableListOf() + val vssNode = request.vssNode vssNode.vssLeafs.forEach { vssLeaf -> - val property = Property(vssLeaf.vssPath, fields) - val response = update(property, vssLeaf.datapoint) + val property = UpdateRequest(vssLeaf.vssPath, vssLeaf.datapoint, *request.fields) + val response = update(property) responses.add(response) } diff --git a/kuksa-sdk/src/main/kotlin/org/eclipse/kuksa/connectivity/databroker/DataBrokerTransporter.kt b/kuksa-sdk/src/main/kotlin/org/eclipse/kuksa/connectivity/databroker/DataBrokerTransporter.kt index c4607222..9016c217 100644 --- a/kuksa-sdk/src/main/kotlin/org/eclipse/kuksa/connectivity/databroker/DataBrokerTransporter.kt +++ b/kuksa-sdk/src/main/kotlin/org/eclipse/kuksa/connectivity/databroker/DataBrokerTransporter.kt @@ -70,13 +70,13 @@ internal class DataBrokerTransporter( */ suspend fun fetch( vssPath: String, - fields: Collection, + vararg fields: Field, ): KuksaValV1.GetResponse { return withContext(defaultDispatcher) { val blockingStub = VALGrpc.newBlockingStub(managedChannel) val entryRequest = KuksaValV1.EntryRequest.newBuilder() .setPath(vssPath) - .addAllFields(fields) + .addAllFields(fields.toSet()) .build() val request = KuksaValV1.GetRequest.newBuilder() .addEntries(entryRequest) @@ -100,8 +100,8 @@ internal class DataBrokerTransporter( */ suspend fun update( vssPath: String, - fields: Collection, updatedDatapoint: Types.Datapoint, + vararg fields: Field, ): KuksaValV1.SetResponse { return withContext(defaultDispatcher) { val blockingStub = VALGrpc.newBlockingStub(managedChannel) diff --git a/kuksa-sdk/src/main/kotlin/org/eclipse/kuksa/connectivity/databroker/listener/PropertyListener.kt b/kuksa-sdk/src/main/kotlin/org/eclipse/kuksa/connectivity/databroker/listener/PropertyListener.kt index 37a2f2ac..bde17974 100644 --- a/kuksa-sdk/src/main/kotlin/org/eclipse/kuksa/connectivity/databroker/listener/PropertyListener.kt +++ b/kuksa-sdk/src/main/kotlin/org/eclipse/kuksa/connectivity/databroker/listener/PropertyListener.kt @@ -23,8 +23,8 @@ import org.eclipse.kuksa.proto.v1.KuksaValV1 import org.eclipse.kuksa.vsscore.model.VssNode /** - * The Listener is used to notify about changes to subscribed [org.eclipse.kuksa.model.Property]. When registering the - * listener to Vehicle.ADAS.ABS this listener will also be notified about changes of children e.g. + * The Listener is used to notify about changes to subscribed VSS paths. When registering the + * listener to e.g. Vehicle.ADAS.ABS this listener will also be notified about changes of the children * Vehicle.ADAS.ABS.IsEnabled or Vehicle.ADAS.ABS.IsEngaged. */ interface PropertyListener : Listener { diff --git a/kuksa-sdk/src/main/kotlin/org/eclipse/kuksa/model/Property.kt b/kuksa-sdk/src/main/kotlin/org/eclipse/kuksa/connectivity/databroker/request/DataBrokerRequest.kt similarity index 67% rename from kuksa-sdk/src/main/kotlin/org/eclipse/kuksa/model/Property.kt rename to kuksa-sdk/src/main/kotlin/org/eclipse/kuksa/connectivity/databroker/request/DataBrokerRequest.kt index b9a11f27..dfb44e1d 100644 --- a/kuksa-sdk/src/main/kotlin/org/eclipse/kuksa/model/Property.kt +++ b/kuksa-sdk/src/main/kotlin/org/eclipse/kuksa/connectivity/databroker/request/DataBrokerRequest.kt @@ -14,25 +14,25 @@ * limitations under the License. * * SPDX-License-Identifier: Apache-2.0 - * */ -package org.eclipse.kuksa.model +package org.eclipse.kuksa.connectivity.databroker.request import org.eclipse.kuksa.proto.v1.Types.Field import org.eclipse.kuksa.proto.v1.Types.Field.FIELD_VALUE /** - * A DataBroker Property. + * Consists of request information for the [org.eclipse.kuksa.connectivity.databroker.DataBrokerConnection]. */ -data class Property( +interface DataBrokerRequest { /** * The VehicleSignalSpecification (VSS) path. */ - val vssPath: String, + val vssPath: String /** - * The corresponding field type of the [Property]. The default is [FIELD_VALUE]. + * The corresponding field type(s) of the [vssPath] request. The [fields] can be used to subscribe to different + * information. The default is [FIELD_VALUE]. */ - val fields: Collection = listOf(FIELD_VALUE), -) + val fields: Array +} diff --git a/kuksa-sdk/src/main/kotlin/org/eclipse/kuksa/connectivity/databroker/request/FetchRequest.kt b/kuksa-sdk/src/main/kotlin/org/eclipse/kuksa/connectivity/databroker/request/FetchRequest.kt new file mode 100644 index 00000000..db7a7cca --- /dev/null +++ b/kuksa-sdk/src/main/kotlin/org/eclipse/kuksa/connectivity/databroker/request/FetchRequest.kt @@ -0,0 +1,29 @@ +/* + * Copyright (c) 2023 Contributors to the Eclipse Foundation + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + * SPDX-License-Identifier: Apache-2.0 + */ + +package org.eclipse.kuksa.connectivity.databroker.request + +import org.eclipse.kuksa.proto.v1.Types + +/** + * Used for fetch requests with [org.eclipse.kuksa.connectivity.databroker.DataBrokerConnection.fetch]. + */ +open class FetchRequest @JvmOverloads constructor( + override val vssPath: String, + override vararg val fields: Types.Field = arrayOf(Types.Field.FIELD_VALUE), +) : DataBrokerRequest diff --git a/kuksa-sdk/src/main/kotlin/org/eclipse/kuksa/connectivity/databroker/request/SubscribeRequest.kt b/kuksa-sdk/src/main/kotlin/org/eclipse/kuksa/connectivity/databroker/request/SubscribeRequest.kt new file mode 100644 index 00000000..0a8648f1 --- /dev/null +++ b/kuksa-sdk/src/main/kotlin/org/eclipse/kuksa/connectivity/databroker/request/SubscribeRequest.kt @@ -0,0 +1,29 @@ +/* + * Copyright (c) 2023 Contributors to the Eclipse Foundation + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + * SPDX-License-Identifier: Apache-2.0 + */ + +package org.eclipse.kuksa.connectivity.databroker.request + +import org.eclipse.kuksa.proto.v1.Types + +/** + * Used for subscribe requests with [org.eclipse.kuksa.connectivity.databroker.DataBrokerConnection.subscribe]. + */ +class SubscribeRequest @JvmOverloads constructor( + override val vssPath: String, + override vararg val fields: Types.Field = arrayOf(Types.Field.FIELD_VALUE), +) : DataBrokerRequest diff --git a/kuksa-sdk/src/main/kotlin/org/eclipse/kuksa/connectivity/databroker/request/UpdateRequest.kt b/kuksa-sdk/src/main/kotlin/org/eclipse/kuksa/connectivity/databroker/request/UpdateRequest.kt new file mode 100644 index 00000000..dab8acea --- /dev/null +++ b/kuksa-sdk/src/main/kotlin/org/eclipse/kuksa/connectivity/databroker/request/UpdateRequest.kt @@ -0,0 +1,31 @@ +/* + * Copyright (c) 2023 Contributors to the Eclipse Foundation + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + * SPDX-License-Identifier: Apache-2.0 + */ + +package org.eclipse.kuksa.connectivity.databroker.request + +import org.eclipse.kuksa.proto.v1.Types +import org.eclipse.kuksa.proto.v1.Types.Datapoint + +/** + * Used for update requests with [org.eclipse.kuksa.connectivity.databroker.DataBrokerConnection.update]. + */ +class UpdateRequest @JvmOverloads constructor( + override val vssPath: String, + val dataPoint: Datapoint, + override vararg val fields: Types.Field = arrayOf(Types.Field.FIELD_VALUE), +) : DataBrokerRequest diff --git a/kuksa-sdk/src/main/kotlin/org/eclipse/kuksa/connectivity/databroker/request/VssNodeDataBrokerRequest.kt b/kuksa-sdk/src/main/kotlin/org/eclipse/kuksa/connectivity/databroker/request/VssNodeDataBrokerRequest.kt new file mode 100644 index 00000000..c4afd34f --- /dev/null +++ b/kuksa-sdk/src/main/kotlin/org/eclipse/kuksa/connectivity/databroker/request/VssNodeDataBrokerRequest.kt @@ -0,0 +1,32 @@ +/* + * Copyright (c) 2023 Contributors to the Eclipse Foundation + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + * SPDX-License-Identifier: Apache-2.0 + */ + +package org.eclipse.kuksa.connectivity.databroker.request + +import org.eclipse.kuksa.vsscore.model.VssNode + +/** + * Uses [VssNode] models to request information for the [org.eclipse.kuksa.connectivity.databroker.DataBrokerConnection] + * which are generated by the [org.eclipse.kuksa.vsscore.annotation.VssModelGenerator]. + */ +interface VssNodeDataBrokerRequest : DataBrokerRequest { + /** + * A generated [VssNode] model. + */ + val vssNode: T +} diff --git a/kuksa-sdk/src/main/kotlin/org/eclipse/kuksa/extension/VssSpecificationExtension.kt b/kuksa-sdk/src/main/kotlin/org/eclipse/kuksa/connectivity/databroker/request/VssNodeFetchRequest.kt similarity index 59% rename from kuksa-sdk/src/main/kotlin/org/eclipse/kuksa/extension/VssSpecificationExtension.kt rename to kuksa-sdk/src/main/kotlin/org/eclipse/kuksa/connectivity/databroker/request/VssNodeFetchRequest.kt index 825581dc..bd42e83c 100644 --- a/kuksa-sdk/src/main/kotlin/org/eclipse/kuksa/extension/VssSpecificationExtension.kt +++ b/kuksa-sdk/src/main/kotlin/org/eclipse/kuksa/connectivity/databroker/request/VssNodeFetchRequest.kt @@ -16,20 +16,17 @@ * SPDX-License-Identifier: Apache-2.0 */ -package org.eclipse.kuksa.extension +package org.eclipse.kuksa.connectivity.databroker.request -import org.eclipse.kuksa.model.Property import org.eclipse.kuksa.proto.v1.Types -import org.eclipse.kuksa.vsscore.model.VssLeaf import org.eclipse.kuksa.vsscore.model.VssNode -import org.eclipse.kuksa.vsscore.model.vssLeafs /** - * Finds all [VssLeaf] heirs for the [VssNode] and converts them into a collection of [Property]. + * Used for fetch requests with a generated [VssNode] model and + * [org.eclipse.kuksa.connectivity.databroker.DataBrokerConnection.fetch]. */ -fun VssNode.createProperties( - vararg fields: Types.Field = arrayOf(Types.Field.FIELD_VALUE), -): Collection { - return vssLeafs - .map { Property(it.vssPath, fields.toSet()) } -} +@Suppress("performance:SpreadOperator") // API convenience > performance +class VssNodeFetchRequest @JvmOverloads constructor( + override val vssNode: T, + override vararg val fields: Types.Field = arrayOf(Types.Field.FIELD_VALUE), +) : VssNodeDataBrokerRequest, FetchRequest(vssNode.vssPath, *fields) diff --git a/kuksa-sdk/src/main/kotlin/org/eclipse/kuksa/connectivity/databroker/request/VssNodeSubscribeRequest.kt b/kuksa-sdk/src/main/kotlin/org/eclipse/kuksa/connectivity/databroker/request/VssNodeSubscribeRequest.kt new file mode 100644 index 00000000..8e7e6c16 --- /dev/null +++ b/kuksa-sdk/src/main/kotlin/org/eclipse/kuksa/connectivity/databroker/request/VssNodeSubscribeRequest.kt @@ -0,0 +1,32 @@ +/* + * Copyright (c) 2023 Contributors to the Eclipse Foundation + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + * SPDX-License-Identifier: Apache-2.0 + */ + +package org.eclipse.kuksa.connectivity.databroker.request + +import org.eclipse.kuksa.proto.v1.Types +import org.eclipse.kuksa.vsscore.model.VssNode + +/** + * Used for subscribe requests with a generated [VssNode] model and + * [org.eclipse.kuksa.connectivity.databroker.DataBrokerConnection.subscribe]. + */ +@Suppress("performance:SpreadOperator") // API convenience > performance +class VssNodeSubscribeRequest @JvmOverloads constructor( + override val vssNode: T, + override vararg val fields: Types.Field = arrayOf(Types.Field.FIELD_VALUE), +) : VssNodeDataBrokerRequest, FetchRequest(vssNode.vssPath, *fields) diff --git a/kuksa-sdk/src/main/kotlin/org/eclipse/kuksa/connectivity/databroker/request/VssNodeUpdateRequest.kt b/kuksa-sdk/src/main/kotlin/org/eclipse/kuksa/connectivity/databroker/request/VssNodeUpdateRequest.kt new file mode 100644 index 00000000..2c9a105f --- /dev/null +++ b/kuksa-sdk/src/main/kotlin/org/eclipse/kuksa/connectivity/databroker/request/VssNodeUpdateRequest.kt @@ -0,0 +1,32 @@ +/* + * Copyright (c) 2023 Contributors to the Eclipse Foundation + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + * SPDX-License-Identifier: Apache-2.0 + */ + +package org.eclipse.kuksa.connectivity.databroker.request + +import org.eclipse.kuksa.proto.v1.Types +import org.eclipse.kuksa.vsscore.model.VssNode + +/** + * Used for update requests with a generated [VssNode] model and + * [org.eclipse.kuksa.connectivity.databroker.DataBrokerConnection.update]. + */ +@Suppress("performance:SpreadOperator") // API convenience > performance +class VssNodeUpdateRequest @JvmOverloads constructor( + override val vssNode: T, + override vararg val fields: Types.Field = arrayOf(Types.Field.FIELD_VALUE), +) : VssNodeDataBrokerRequest, FetchRequest(vssNode.vssPath, *fields) diff --git a/kuksa-sdk/src/test/kotlin/org/eclipse/kuksa/connectivity/authentication/DataBrokerConnectorAuthenticationTest.kt b/kuksa-sdk/src/test/kotlin/org/eclipse/kuksa/connectivity/authentication/DataBrokerConnectorAuthenticationTest.kt index 168adf49..5f18916b 100644 --- a/kuksa-sdk/src/test/kotlin/org/eclipse/kuksa/connectivity/authentication/DataBrokerConnectorAuthenticationTest.kt +++ b/kuksa-sdk/src/test/kotlin/org/eclipse/kuksa/connectivity/authentication/DataBrokerConnectorAuthenticationTest.kt @@ -22,7 +22,8 @@ import io.kotest.core.spec.style.BehaviorSpec import io.kotest.matchers.shouldBe import org.eclipse.kuksa.connectivity.databroker.DataBrokerConnectionTest import org.eclipse.kuksa.connectivity.databroker.DataBrokerConnectorProvider -import org.eclipse.kuksa.model.Property +import org.eclipse.kuksa.connectivity.databroker.request.FetchRequest +import org.eclipse.kuksa.connectivity.databroker.request.UpdateRequest import org.eclipse.kuksa.proto.v1.Types import org.eclipse.kuksa.test.kotest.Authentication import org.eclipse.kuksa.test.kotest.CustomDatabroker @@ -43,6 +44,7 @@ class DataBrokerConnectorAuthenticationTest : BehaviorSpec({ given("A DataBrokerConnectorProvider") { val dataBrokerConnectorProvider = DataBrokerConnectorProvider() + val speedVssPath = "Vehicle.Speed" and("an insecure DataBrokerConnector with a READ_WRITE_ALL JWT") { val jwtFileStream = JwtType.READ_WRITE_ALL.asInputStream() @@ -50,10 +52,10 @@ class DataBrokerConnectorAuthenticationTest : BehaviorSpec({ and("a successfully established connection") { val connection = dataBrokerConnector.connect() - val property = Property("Vehicle.Speed") `when`("Reading Vehicle.Speed") { - val response = connection.fetch(property) + val fetchRequest = FetchRequest(speedVssPath) + val response = connection.fetch(fetchRequest) then("No error should occur") { response.errorsList.size shouldBe 0 @@ -63,8 +65,9 @@ class DataBrokerConnectorAuthenticationTest : BehaviorSpec({ `when`("Writing the VALUE of Vehicle.Speed") { val nextFloat = random.nextFloat() * 100F val datapoint = Types.Datapoint.newBuilder().setFloat(nextFloat).build() + val updateRequest = UpdateRequest(speedVssPath, datapoint) - val response = connection.update(property, datapoint) + val response = connection.update(updateRequest) then("No error should occur") { response.errorsList.size shouldBe 0 @@ -79,10 +82,10 @@ class DataBrokerConnectorAuthenticationTest : BehaviorSpec({ and("a successfully established connection") { val connection = dataBrokerConnector.connect() - val property = Property("Vehicle.Speed") `when`("Reading Vehicle.Speed") { - val response = connection.fetch(property) + val fetchRequest = FetchRequest(speedVssPath) + val response = connection.fetch(fetchRequest) then("No error should appear") { response.errorsList.size shouldBe 0 @@ -92,8 +95,8 @@ class DataBrokerConnectorAuthenticationTest : BehaviorSpec({ `when`("Writing the VALUE of Vehicle.Speed") { val nextFloat = random.nextFloat() * 100F val datapoint = Types.Datapoint.newBuilder().setFloat(nextFloat).build() - - val response = connection.update(property, datapoint) + val updateRequest = UpdateRequest(speedVssPath, datapoint) + val response = connection.update(updateRequest) then("An error should occur") { response.errorsList.size shouldBe 1 @@ -108,13 +111,12 @@ class DataBrokerConnectorAuthenticationTest : BehaviorSpec({ and("a successfully established connection") { val connection = dataBrokerConnector.connect() - val actuatorTargetProperty = Property( - "Vehicle.Body.Mirrors.DriverSide.Pan", - listOf(Types.Field.FIELD_ACTUATOR_TARGET), - ) + val panVssPath = "Vehicle.Body.Mirrors.DriverSide.Pan" + val actuatorTargetField = Types.Field.FIELD_ACTUATOR_TARGET `when`("Reading the ACTUATOR_TARGET of Vehicle.Body.Mirrors.DriverSide.Pan") { - val response = connection.fetch(actuatorTargetProperty) + val fetchRequest = FetchRequest(panVssPath, actuatorTargetField) + val response = connection.fetch(fetchRequest) then("No error should occur") { response.errorsList.size shouldBe 0 @@ -124,21 +126,18 @@ class DataBrokerConnectorAuthenticationTest : BehaviorSpec({ `when`("Writing to the ACTUATOR_TARGET of Vehicle.Body.Mirrors.DriverSide.Pan") { val nextInt = random.nextInt(-100..100) val datapoint = Types.Datapoint.newBuilder().setInt32(nextInt).build() + val updateRequest = UpdateRequest(panVssPath, datapoint, actuatorTargetField) - val response = connection.update(actuatorTargetProperty, datapoint) + val response = connection.update(updateRequest) then("An error should occur") { response.errorsList.size shouldBe 1 } } - val valueProperty = Property( - "Vehicle.Speed", - listOf(Types.Field.FIELD_VALUE), - ) - `when`("Reading the VALUE of Vehicle.Speed") { - val response = connection.fetch(valueProperty) + val fetchRequest = FetchRequest(speedVssPath) + val response = connection.fetch(fetchRequest) then("No error should occur") { response.errorsList.size shouldBe 0 @@ -148,8 +147,9 @@ class DataBrokerConnectorAuthenticationTest : BehaviorSpec({ `when`("Writing the VALUE of Vehicle.Speed") { val nextFloat = random.nextFloat() * 100F val datapoint = Types.Datapoint.newBuilder().setFloat(nextFloat).build() + val updateRequest = UpdateRequest(speedVssPath, datapoint) - val response = connection.update(valueProperty, datapoint) + val response = connection.update(updateRequest) then("No error should occur") { response.errorsList.size shouldBe 0 diff --git a/kuksa-sdk/src/test/kotlin/org/eclipse/kuksa/connectivity/databroker/DataBrokerConnectionTest.kt b/kuksa-sdk/src/test/kotlin/org/eclipse/kuksa/connectivity/databroker/DataBrokerConnectionTest.kt index a8b7e9c2..074d4e17 100644 --- a/kuksa-sdk/src/test/kotlin/org/eclipse/kuksa/connectivity/databroker/DataBrokerConnectionTest.kt +++ b/kuksa-sdk/src/test/kotlin/org/eclipse/kuksa/connectivity/databroker/DataBrokerConnectionTest.kt @@ -32,8 +32,13 @@ import io.mockk.verify import kotlinx.coroutines.runBlocking import org.eclipse.kuksa.connectivity.databroker.listener.DisconnectListener import org.eclipse.kuksa.connectivity.databroker.listener.PropertyListener +import org.eclipse.kuksa.connectivity.databroker.request.FetchRequest +import org.eclipse.kuksa.connectivity.databroker.request.SubscribeRequest +import org.eclipse.kuksa.connectivity.databroker.request.UpdateRequest +import org.eclipse.kuksa.connectivity.databroker.request.VssNodeFetchRequest +import org.eclipse.kuksa.connectivity.databroker.request.VssNodeSubscribeRequest +import org.eclipse.kuksa.connectivity.databroker.request.VssNodeUpdateRequest import org.eclipse.kuksa.mocking.FriendlyVssNodeListener -import org.eclipse.kuksa.model.Property import org.eclipse.kuksa.proto.v1.KuksaValV1 import org.eclipse.kuksa.proto.v1.Types import org.eclipse.kuksa.test.kotest.DefaultDatabroker @@ -49,14 +54,14 @@ class DataBrokerConnectionTest : BehaviorSpec({ given("A successfully established connection to the DataBroker") { val dataBrokerConnection = connectToDataBrokerBlocking() - and("A Property with a valid VSS Path") { + and("A request with a valid VSS Path") { val vssPath = "Vehicle.Acceleration.Lateral" - val fields = listOf(Types.Field.FIELD_VALUE) - val property = Property(vssPath, fields) + val field = Types.Field.FIELD_VALUE + val subscribeRequest = SubscribeRequest(vssPath, field) `when`("Subscribing to the Property") { val propertyListener = mockk(relaxed = true) - dataBrokerConnection.subscribe(property, propertyListener) + dataBrokerConnection.subscribe(subscribeRequest, propertyListener) then("The #onPropertyChanged method is triggered") { val capturingSlot = slot>() @@ -75,7 +80,8 @@ class DataBrokerConnectionTest : BehaviorSpec({ val random = Random(System.currentTimeMillis()) val newValue = random.nextFloat() val datapoint = Types.Datapoint.newBuilder().setFloat(newValue).build() - dataBrokerConnection.update(property, datapoint) + val updateRequest = UpdateRequest(vssPath, datapoint, field) + dataBrokerConnection.update(updateRequest) then("The #onPropertyChanged callback is triggered with the new value") { val capturingSlot = slot>() @@ -96,14 +102,16 @@ class DataBrokerConnectionTest : BehaviorSpec({ val validDatapoint = createRandomFloatDatapoint() `when`("Updating the Property with a valid Datapoint") { // make sure that the value is set and known to us - val response = dataBrokerConnection.update(property, validDatapoint) + val updateRequest = UpdateRequest(vssPath, validDatapoint, field) + val response = dataBrokerConnection.update(updateRequest) then("No error should appear") { Assertions.assertFalse(response.hasError()) } and("When fetching it afterwards") { - val response1 = dataBrokerConnection.fetch(property) + val fetchRequest = FetchRequest(vssPath) + val response1 = dataBrokerConnection.fetch(fetchRequest) then("The response contains the correctly set value") { val entriesList = response1.entriesList @@ -116,7 +124,8 @@ class DataBrokerConnectionTest : BehaviorSpec({ `when`("Updating the Property with a Datapoint of a wrong/different type") { val datapoint = createRandomIntDatapoint() - val response = dataBrokerConnection.update(property, datapoint) + val updateRequest = UpdateRequest(vssPath, datapoint) + val response = dataBrokerConnection.update(updateRequest) then("It should fail with an errorCode 400 (type mismatch)") { val errorsList = response.errorsList @@ -128,7 +137,8 @@ class DataBrokerConnectionTest : BehaviorSpec({ } and("Fetching it afterwards") { - val getResponse = dataBrokerConnection.fetch(property) + val fetchRequest = FetchRequest(vssPath) + val getResponse = dataBrokerConnection.fetch(fetchRequest) then("The response contains the correctly set value") { val entriesList = getResponse.entriesList @@ -140,20 +150,22 @@ class DataBrokerConnectionTest : BehaviorSpec({ } } - and("A Specification") { - val specification = VssDriver() - val property = Property(specification.heartRate.vssPath) + and("A VssNode") { + val vssDriver = VssDriver() - `when`("Fetching the specification") { + `when`("Fetching the node") { and("The initial value is different from the default for a child") { val newHeartRateValue = 60 val datapoint = Types.Datapoint.newBuilder().setUint32(newHeartRateValue).build() + val updateRequest = UpdateRequest(vssDriver.heartRate.vssPath, datapoint) - dataBrokerConnection.update(property, datapoint) + dataBrokerConnection.update(updateRequest) + + val fetchRequest = VssNodeFetchRequest(vssDriver) + val updatedDriver = dataBrokerConnection.fetch(fetchRequest) then("Every child property has been updated with the correct value") { - val updatedDriver = dataBrokerConnection.fetch(specification) val heartRate = updatedDriver.heartRate heartRate.value shouldBe newHeartRateValue @@ -161,9 +173,10 @@ class DataBrokerConnectionTest : BehaviorSpec({ } } - `when`("Subscribing to the specification") { + `when`("Subscribing to the node") { val specificationListener = FriendlyVssNodeListener() - dataBrokerConnection.subscribe(specification, listener = specificationListener) + val subscribeRequest = VssNodeSubscribeRequest(vssDriver) + dataBrokerConnection.subscribe(subscribeRequest, listener = specificationListener) then("The #onSpecificationChanged method is triggered") { eventually(1.seconds) { @@ -173,11 +186,12 @@ class DataBrokerConnectionTest : BehaviorSpec({ and("The initial value is different from the default for a child") { val newHeartRateValue = 70 - val datapoint = Types.Datapoint.newBuilder().setUint32(newHeartRateValue).build() + val newHeartRateVssNode = vssDriver.heartRate.copy(value = newHeartRateValue) + val updateRequest = VssNodeUpdateRequest(newHeartRateVssNode) - dataBrokerConnection.update(property, datapoint) + dataBrokerConnection.update(updateRequest) - then("Every child property has been updated with the correct value") { + then("Every child node has been updated with the correct value") { eventually(1.seconds) { specificationListener.updatedSpecifications.size shouldBe 2 } @@ -189,13 +203,14 @@ class DataBrokerConnectionTest : BehaviorSpec({ } } - and("Any subscribed Property was changed") { + and("Any subscribed node was changed") { val newHeartRateValue = 50 - val datapoint = Types.Datapoint.newBuilder().setUint32(newHeartRateValue).build() + val newHeartRateVssNode = vssDriver.heartRate.copy(value = newHeartRateValue) + val updateRequest = VssNodeUpdateRequest(newHeartRateVssNode) - dataBrokerConnection.update(property, datapoint) + dataBrokerConnection.update(updateRequest) - then("The subscribed Specification should be updated") { + then("The subscribed vssNode should be updated") { eventually(1.seconds) { specificationListener.updatedSpecifications.size shouldBe 3 } @@ -210,12 +225,12 @@ class DataBrokerConnectionTest : BehaviorSpec({ } and("A Property with an INVALID VSS Path") { - val fields = listOf(Types.Field.FIELD_VALUE) - val property = Property("Vehicle.Some.Unknown.Path", fields) + val invalidVssPath = "Vehicle.Some.Unknown.Path" `when`("Trying to subscribe to the INVALID Property") { val propertyListener = mockk(relaxed = true) - dataBrokerConnection.subscribe(property, propertyListener) + val subscribeRequest = SubscribeRequest(invalidVssPath) + dataBrokerConnection.subscribe(subscribeRequest, propertyListener) then("The PropertyListener#onError method should be triggered with 'NOT_FOUND' (Path not found)") { val capturingSlot = slot() @@ -228,7 +243,8 @@ class DataBrokerConnectionTest : BehaviorSpec({ `when`("Trying to update the INVALID property") { // make sure that the value is set and known to us val datapoint = createRandomFloatDatapoint() - val response = dataBrokerConnection.update(property, datapoint) + val updateRequest = UpdateRequest(invalidVssPath, datapoint) + val response = dataBrokerConnection.update(updateRequest) then("It should fail with an errorCode 404 (path not found)") { val errorsList = response.errorsList @@ -241,7 +257,8 @@ class DataBrokerConnectionTest : BehaviorSpec({ } `when`("Trying to fetch the INVALID property") { - val response = dataBrokerConnection.fetch(property) + val fetchRequest = FetchRequest(invalidVssPath) + val response = dataBrokerConnection.fetch(fetchRequest) then("The response should not contain any entries") { Assertions.assertEquals(0, response.entriesList.size) diff --git a/kuksa-sdk/src/test/kotlin/org/eclipse/kuksa/connectivity/databroker/DataBrokerTransporterTest.kt b/kuksa-sdk/src/test/kotlin/org/eclipse/kuksa/connectivity/databroker/DataBrokerTransporterTest.kt index b3b74028..93fd8b1d 100644 --- a/kuksa-sdk/src/test/kotlin/org/eclipse/kuksa/connectivity/databroker/DataBrokerTransporterTest.kt +++ b/kuksa-sdk/src/test/kotlin/org/eclipse/kuksa/connectivity/databroker/DataBrokerTransporterTest.kt @@ -47,14 +47,14 @@ class DataBrokerTransporterTest : BehaviorSpec({ and("Some VSS-related data") { val vssPath = "Vehicle.ADAS.CruiseControl.SpeedSet" - val fields = listOf(Types.Field.FIELD_VALUE) + val field = Types.Field.FIELD_VALUE val random = Random(System.currentTimeMillis()) val valueToSet = random.nextInt(250).toFloat() - `when`("Updating the $fields of $vssPath to $valueToSet km/h") { + `when`("Updating the $field of $vssPath to $valueToSet km/h") { val updatedDatapoint = Types.Datapoint.newBuilder().setFloat(valueToSet).build() val result = kotlin.runCatching { - classUnderTest.update(vssPath, fields, updatedDatapoint) + classUnderTest.update(vssPath, updatedDatapoint, field) } then("No Exception should be thrown") { @@ -69,7 +69,7 @@ class DataBrokerTransporterTest : BehaviorSpec({ } `when`("Fetching the Value of Vehicle.ADAS.CruiseControl.SpeedSet") { - val property = classUnderTest.fetch(vssPath, fields) + val property = classUnderTest.fetch(vssPath, field) then("It should return the correct value") { val dataEntry = property.getEntries(0) @@ -78,11 +78,11 @@ class DataBrokerTransporterTest : BehaviorSpec({ } } - `when`("Trying to fetch the $fields from an invalid VSS Path") { + `when`("Trying to fetch the $field from an invalid VSS Path") { val invalidVssPath = "Vehicle.This.Path.Is.Invalid" val result = kotlin.runCatching { - classUnderTest.fetch(invalidVssPath, fields) + classUnderTest.fetch(invalidVssPath, field) } then("No Exception should be thrown") { diff --git a/kuksa-sdk/src/test/kotlin/org/eclipse/kuksa/connectivity/databroker/subscription/DataBrokerSubscriberTest.kt b/kuksa-sdk/src/test/kotlin/org/eclipse/kuksa/connectivity/databroker/subscription/DataBrokerSubscriberTest.kt index 006eb5a0..b138473a 100644 --- a/kuksa-sdk/src/test/kotlin/org/eclipse/kuksa/connectivity/databroker/subscription/DataBrokerSubscriberTest.kt +++ b/kuksa-sdk/src/test/kotlin/org/eclipse/kuksa/connectivity/databroker/subscription/DataBrokerSubscriberTest.kt @@ -27,9 +27,9 @@ import io.mockk.every import io.mockk.mockk import io.mockk.verify import kotlinx.coroutines.delay +import org.eclipse.kuksa.connectivity.databroker.DataBrokerConnectorProvider import org.eclipse.kuksa.connectivity.databroker.DataBrokerTransporter import org.eclipse.kuksa.connectivity.databroker.listener.PropertyListener -import org.eclipse.kuksa.connectivity.databroker.DataBrokerConnectorProvider import org.eclipse.kuksa.extensions.toggleBoolean import org.eclipse.kuksa.extensions.updateRandomFloatValue import org.eclipse.kuksa.extensions.updateRandomUint32Value diff --git a/kuksa-sdk/src/test/kotlin/org/eclipse/kuksa/extensions/DataBrokerTransporterExtensions.kt b/kuksa-sdk/src/test/kotlin/org/eclipse/kuksa/extensions/DataBrokerTransporterExtensions.kt index acd132e3..b046bd44 100644 --- a/kuksa-sdk/src/test/kotlin/org/eclipse/kuksa/extensions/DataBrokerTransporterExtensions.kt +++ b/kuksa-sdk/src/test/kotlin/org/eclipse/kuksa/extensions/DataBrokerTransporterExtensions.kt @@ -33,10 +33,8 @@ internal suspend fun DataBrokerTransporter.updateRandomFloatValue( val randomFloat = randomValue.toFloat() val updatedDatapoint = Types.Datapoint.newBuilder().setFloat(randomFloat).build() - val fields = listOf(Types.Field.FIELD_VALUE) - try { - update(vssPath, fields, updatedDatapoint) + update(vssPath, updatedDatapoint, Types.Field.FIELD_VALUE) } catch (e: Exception) { fail("Updating $vssPath to $randomFloat failed: $e") } @@ -53,7 +51,7 @@ internal suspend fun DataBrokerTransporter.updateRandomUint32Value( val updatedDatapoint = Types.Datapoint.newBuilder().setUint32(randomValue).build() try { - update(vssPath, listOf(Types.Field.FIELD_VALUE), updatedDatapoint) + update(vssPath, updatedDatapoint, Types.Field.FIELD_VALUE) } catch (e: Exception) { fail("Updating $vssPath to $randomValue failed: $e") } @@ -62,17 +60,17 @@ internal suspend fun DataBrokerTransporter.updateRandomUint32Value( } internal suspend fun DataBrokerTransporter.toggleBoolean(vssPath: String): Boolean { - val fields = listOf(Types.Field.FIELD_VALUE) + val field = Types.Field.FIELD_VALUE var newBoolean: Boolean? = null try { - val response = fetch(vssPath, fields) + val response = fetch(vssPath, field) val currentBool = response.entriesList[0].value.bool newBoolean = !currentBool val newDatapoint = Types.Datapoint.newBuilder().setBool(newBoolean).build() - update(vssPath, fields, newDatapoint) + update(vssPath, newDatapoint, field) } catch (e: Exception) { fail("Updating $vssPath to $newBoolean failed: $e") } diff --git a/samples/src/main/java/com/example/sample/JavaActivity.java b/samples/src/main/java/com/example/sample/JavaActivity.java index c6376b34..1d0945db 100644 --- a/samples/src/main/java/com/example/sample/JavaActivity.java +++ b/samples/src/main/java/com/example/sample/JavaActivity.java @@ -22,14 +22,19 @@ import androidx.annotation.NonNull; import androidx.appcompat.app.AppCompatActivity; -import org.eclipse.kuksa.coroutine.CoroutineCallback; +import org.eclipse.kuksa.connectivity.authentication.JsonWebToken; import org.eclipse.kuksa.connectivity.databroker.DataBrokerConnection; import org.eclipse.kuksa.connectivity.databroker.DataBrokerConnector; import org.eclipse.kuksa.connectivity.databroker.listener.DisconnectListener; import org.eclipse.kuksa.connectivity.databroker.listener.PropertyListener; import org.eclipse.kuksa.connectivity.databroker.listener.VssNodeListener; -import org.eclipse.kuksa.connectivity.authentication.JsonWebToken; -import org.eclipse.kuksa.model.Property; +import org.eclipse.kuksa.connectivity.databroker.request.FetchRequest; +import org.eclipse.kuksa.connectivity.databroker.request.SubscribeRequest; +import org.eclipse.kuksa.connectivity.databroker.request.UpdateRequest; +import org.eclipse.kuksa.connectivity.databroker.request.VssNodeFetchRequest; +import org.eclipse.kuksa.connectivity.databroker.request.VssNodeSubscribeRequest; +import org.eclipse.kuksa.connectivity.databroker.request.VssNodeUpdateRequest; +import org.eclipse.kuksa.coroutine.CoroutineCallback; import org.eclipse.kuksa.proto.v1.KuksaValV1; import org.eclipse.kuksa.proto.v1.KuksaValV1.GetResponse; import org.eclipse.kuksa.proto.v1.Types; @@ -39,7 +44,6 @@ import java.io.IOException; import java.io.InputStream; import java.util.Collection; -import java.util.Collections; import java.util.List; import javax.annotation.Nullable; @@ -135,10 +139,11 @@ public void disconnect() { dataBrokerConnection = null; } - public void fetchProperty(Property property) { + public void fetchProperty() { if (dataBrokerConnection == null) return; - dataBrokerConnection.fetch(property, new CoroutineCallback() { + FetchRequest request = new FetchRequest("Vehicle.Speed", Types.Field.FIELD_VALUE); + dataBrokerConnection.fetch(request, new CoroutineCallback() { @Override public void onSuccess(GetResponse result) { // handle result @@ -151,10 +156,14 @@ public void onError(@NonNull Throwable throwable) { }); } - public void updateProperty(Property property, Datapoint datapoint) { + public void updateProperty() { if (dataBrokerConnection == null) return; - dataBrokerConnection.update(property, datapoint, new CoroutineCallback() { + Datapoint datapoint = Datapoint.newBuilder() + .setFloat(50f) + .build(); + UpdateRequest request = new UpdateRequest("Vehicle.Speed", datapoint, Types.Field.FIELD_VALUE); + dataBrokerConnection.update(request, new CoroutineCallback() { @Override public void onSuccess(KuksaValV1.SetResponse result) { // handle result @@ -167,10 +176,11 @@ public void onError(@NonNull Throwable error) { }); } - public void subscribeProperty(Property property) { + public void subscribeProperty() { if (dataBrokerConnection == null) return; - dataBrokerConnection.subscribe(property, new PropertyListener() { + SubscribeRequest request = new SubscribeRequest("Vehicle.Speed", Types.Field.FIELD_VALUE); + dataBrokerConnection.subscribe(request, new PropertyListener() { @Override public void onPropertyChanged(@NonNull List entryUpdates) { for (KuksaValV1.EntryUpdate entryUpdate : entryUpdates) { @@ -193,14 +203,17 @@ public void onError(@NonNull Throwable throwable) { }); } - // region: Specifications + // region: VSS generated models public void fetchNode() { if (dataBrokerConnection == null) return; VssVehicle.VssSpeed vssSpeed = new VssVehicle.VssSpeed(); - dataBrokerConnection.fetch( + VssNodeFetchRequest request = new VssNodeFetchRequest<>( vssSpeed, - Collections.singleton(Types.Field.FIELD_VALUE), + Types.Field.FIELD_VALUE + ); + dataBrokerConnection.fetch( + request, new CoroutineCallback() { @Override public void onSuccess(@Nullable VssVehicle.VssSpeed result) { @@ -221,9 +234,12 @@ public void updateNode() { if (dataBrokerConnection == null) return; VssVehicle.VssSpeed vssSpeed = new VssVehicle.VssSpeed(100f); - dataBrokerConnection.update( + VssNodeUpdateRequest request = new VssNodeUpdateRequest<>( vssSpeed, - Collections.singleton(Types.Field.FIELD_VALUE), + Types.Field.FIELD_VALUE + ); + dataBrokerConnection.update( + request, new CoroutineCallback>() { @Override public void onSuccess(@Nullable Collection result) { @@ -242,9 +258,12 @@ public void subscribeNode() { if (dataBrokerConnection == null) return; VssVehicle.VssSpeed vssSpeed = new VssVehicle.VssSpeed(); - dataBrokerConnection.subscribe( + VssNodeSubscribeRequest request = new VssNodeSubscribeRequest<>( vssSpeed, - Collections.singleton(Types.Field.FIELD_VALUE), + Types.Field.FIELD_VALUE + ); + dataBrokerConnection.subscribe( + request, new VssNodeListener() { @Override public void onNodeChanged(@NonNull VssVehicle.VssSpeed vssNode) { diff --git a/samples/src/main/kotlin/com/example/sample/KotlinActivity.kt b/samples/src/main/kotlin/com/example/sample/KotlinActivity.kt index f8666fb8..bd740e2f 100644 --- a/samples/src/main/kotlin/com/example/sample/KotlinActivity.kt +++ b/samples/src/main/kotlin/com/example/sample/KotlinActivity.kt @@ -33,7 +33,12 @@ import org.eclipse.kuksa.connectivity.databroker.DataBrokerException import org.eclipse.kuksa.connectivity.databroker.listener.DisconnectListener import org.eclipse.kuksa.connectivity.databroker.listener.PropertyListener import org.eclipse.kuksa.connectivity.databroker.listener.VssNodeListener -import org.eclipse.kuksa.model.Property +import org.eclipse.kuksa.connectivity.databroker.request.FetchRequest +import org.eclipse.kuksa.connectivity.databroker.request.SubscribeRequest +import org.eclipse.kuksa.connectivity.databroker.request.UpdateRequest +import org.eclipse.kuksa.connectivity.databroker.request.VssNodeFetchRequest +import org.eclipse.kuksa.connectivity.databroker.request.VssNodeSubscribeRequest +import org.eclipse.kuksa.connectivity.databroker.request.VssNodeUpdateRequest import org.eclipse.kuksa.proto.v1.KuksaValV1 import org.eclipse.kuksa.proto.v1.Types import org.eclipse.kuksa.proto.v1.Types.Datapoint @@ -114,10 +119,11 @@ class KotlinActivity : AppCompatActivity() { dataBrokerConnection = null } - fun fetchProperty(property: Property) { + fun fetchProperty() { + val request = FetchRequest("Vehicle.Speed", Types.Field.FIELD_VALUE) lifecycleScope.launch { try { - val response = dataBrokerConnection?.fetch(property) ?: return@launch + val response = dataBrokerConnection?.fetch(request) ?: return@launch // handle response } catch (e: DataBrokerException) { // handle error @@ -125,10 +131,14 @@ class KotlinActivity : AppCompatActivity() { } } - fun updateProperty(property: Property, datapoint: Datapoint) { + fun updateProperty() { + val datapoint = Datapoint.newBuilder() + .setFloat(50f) + .build() + val request = UpdateRequest("Vehicle.Speed", datapoint, Types.Field.FIELD_VALUE) lifecycleScope.launch { try { - val response = dataBrokerConnection?.update(property, datapoint) ?: return@launch + val response = dataBrokerConnection?.update(request) ?: return@launch // handle response } catch (e: DataBrokerException) { // handle error @@ -136,7 +146,8 @@ class KotlinActivity : AppCompatActivity() { } } - fun subscribeProperty(property: Property) { + fun subscribeProperty() { + val request = SubscribeRequest("Vehicle.Speed", Types.Field.FIELD_VALUE) val propertyListener = object : PropertyListener { override fun onPropertyChanged(entryUpdates: List) { entryUpdates.forEach { entryUpdate -> @@ -156,7 +167,7 @@ class KotlinActivity : AppCompatActivity() { } } - dataBrokerConnection?.subscribe(property, propertyListener) + dataBrokerConnection?.subscribe(request, propertyListener) } // region: VSS generated models @@ -164,7 +175,8 @@ class KotlinActivity : AppCompatActivity() { lifecycleScope.launch { try { val vssSpeed = VssVehicle.VssSpeed() - val updatedSpeed = dataBrokerConnection?.fetch(vssSpeed, listOf(Types.Field.FIELD_VALUE)) + val request = VssNodeFetchRequest(vssSpeed, Types.Field.FIELD_VALUE) + val updatedSpeed = dataBrokerConnection?.fetch(request) val speed = updatedSpeed?.value } catch (e: DataBrokerException) { // handle error @@ -175,15 +187,16 @@ class KotlinActivity : AppCompatActivity() { fun updateNode() { lifecycleScope.launch { val vssSpeed = VssVehicle.VssSpeed(value = 100f) - dataBrokerConnection?.update(vssSpeed, listOf(Types.Field.FIELD_VALUE)) + val request = VssNodeUpdateRequest(vssSpeed, Types.Field.FIELD_VALUE) + dataBrokerConnection?.update(request) } } fun subscribeNode() { val vssSpeed = VssVehicle.VssSpeed(value = 100f) + val request = VssNodeSubscribeRequest(vssSpeed, Types.Field.FIELD_VALUE) dataBrokerConnection?.subscribe( - vssSpeed, - listOf(Types.Field.FIELD_VALUE), + request, object : VssNodeListener { override fun onNodeChanged(vssNode: VssVehicle.VssSpeed) { val speed = vssSpeed.value diff --git a/vss-core/src/main/kotlin/org/eclipse/kuksa/vsscore/model/VssNode.kt b/vss-core/src/main/kotlin/org/eclipse/kuksa/vsscore/model/VssNode.kt index 25d5e9cc..6a9fef00 100644 --- a/vss-core/src/main/kotlin/org/eclipse/kuksa/vsscore/model/VssNode.kt +++ b/vss-core/src/main/kotlin/org/eclipse/kuksa/vsscore/model/VssNode.kt @@ -24,14 +24,34 @@ import kotlin.reflect.KClass import kotlin.reflect.full.declaredMemberProperties /** - * Represents a node inside a VSS file. it represents the most common properties. - * The [uuid] is a mandatory field and should never be empty. + * Represents a node inside a VSS (file) data structure. it represents the most common properties. */ interface VssNode { + /** + * The [uuid] is a mandatory field and should never be empty. + */ val uuid: String + + /** + * Defines the path to the property inside the VSS tree structure. + * Example: Vehicle.Body.Horn.IsActive + */ val vssPath: String + + /** + * Simple description of the property. + */ val description: String + + /** + * Most relevant for [VssLeaf] nodes. They can be of the type "Sensor" or "Actuator". + * For Nodes with children this will always be "branch". + */ val type: String + + /** + * An optional additional comment for the [VssNode]. + */ val comment: String /** @@ -48,9 +68,13 @@ interface VssNode { } /** - * Some [VssNode] may have an additional [value] property. These are children which are not parents. + * Some [VssNode] may have an additional [value] property. These are children [VssLeaf] which do not have other + * children. */ interface VssLeaf : VssNode { + /** + * A primitive type value. + */ val value: T } From 6ad44591d0a136efc0db76bf5af357ee91305b4b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mark=20Hu=CC=88sers?= Date: Tue, 5 Mar 2024 17:23:19 +0100 Subject: [PATCH 11/20] chore: Rename PropertyListener -> VssPathListener --- .../databroker/JavaDataBrokerEngine.java | 10 ++-- .../kuksa/testapp/KuksaDataBrokerActivity.kt | 12 ++--- .../testapp/databroker/DataBrokerEngine.kt | 6 +-- .../databroker/KotlinDataBrokerEngine.kt | 10 ++-- docs/QUICKSTART.md | 25 ++++----- docs/kuksa-sdk_class-diagram.puml | 53 +++++++++++++------ .../databroker/DataBrokerConnection.kt | 26 ++++----- .../databroker/DataBrokerTransporter.kt | 2 +- ...PropertyListener.kt => VssPathListener.kt} | 4 +- .../databroker/request/SubscribeRequest.kt | 2 +- .../databroker/request/UpdateRequest.kt | 2 +- .../databroker/request/VssNodeFetchRequest.kt | 5 +- .../request/VssNodeSubscribeRequest.kt | 5 +- .../request/VssNodeUpdateRequest.kt | 5 +- .../subscription/DataBrokerSubscriber.kt | 26 ++++----- .../subscription/DataBrokerSubscription.kt | 8 +-- ...ertyListener.kt => VssNodePathListener.kt} | 10 ++-- .../databroker/DataBrokerConnectionTest.kt | 18 +++---- .../databroker/DataBrokerTransporterTest.kt | 14 ++--- .../subscription/DataBrokerSubscriberTest.kt | 28 +++++----- ...Listener.kt => FriendlyVssPathListener.kt} | 6 +-- .../java/com/example/sample/JavaActivity.java | 6 +-- .../com/example/sample/KotlinActivity.kt | 8 +-- 23 files changed, 161 insertions(+), 130 deletions(-) rename kuksa-sdk/src/main/kotlin/org/eclipse/kuksa/connectivity/databroker/listener/{PropertyListener.kt => VssPathListener.kt} (94%) rename kuksa-sdk/src/main/kotlin/org/eclipse/kuksa/connectivity/databroker/subscription/{SpecificationPropertyListener.kt => VssNodePathListener.kt} (86%) rename kuksa-sdk/src/test/kotlin/org/eclipse/kuksa/mocking/{FriendlyPropertyListener.kt => FriendlyVssPathListener.kt} (83%) diff --git a/app/src/main/java/org/eclipse/kuksa/testapp/databroker/JavaDataBrokerEngine.java b/app/src/main/java/org/eclipse/kuksa/testapp/databroker/JavaDataBrokerEngine.java index d99ccf4a..36c2be9c 100644 --- a/app/src/main/java/org/eclipse/kuksa/testapp/databroker/JavaDataBrokerEngine.java +++ b/app/src/main/java/org/eclipse/kuksa/testapp/databroker/JavaDataBrokerEngine.java @@ -26,7 +26,7 @@ import org.eclipse.kuksa.connectivity.databroker.DataBrokerConnection; import org.eclipse.kuksa.connectivity.databroker.DataBrokerConnector; import org.eclipse.kuksa.connectivity.databroker.listener.DisconnectListener; -import org.eclipse.kuksa.connectivity.databroker.listener.PropertyListener; +import org.eclipse.kuksa.connectivity.databroker.listener.VssPathListener; import org.eclipse.kuksa.connectivity.databroker.listener.VssNodeListener; import org.eclipse.kuksa.connectivity.databroker.request.FetchRequest; import org.eclipse.kuksa.connectivity.databroker.request.SubscribeRequest; @@ -125,12 +125,12 @@ public void update( } @Override - public void subscribe(@NonNull SubscribeRequest request, @NonNull PropertyListener propertyListener) { + public void subscribe(@NonNull SubscribeRequest request, @NonNull VssPathListener listener) { if (dataBrokerConnection == null) { return; } - dataBrokerConnection.subscribe(request, propertyListener); + dataBrokerConnection.subscribe(request, listener); } @Override @@ -194,9 +194,9 @@ public void unregisterDisconnectListener(@NonNull DisconnectListener listener) { } @Override - public void unsubscribe(@NonNull SubscribeRequest request, @NonNull PropertyListener propertyListener) { + public void unsubscribe(@NonNull SubscribeRequest request, @NonNull VssPathListener listener) { if (dataBrokerConnection != null) { - dataBrokerConnection.unsubscribe(request, propertyListener); + dataBrokerConnection.unsubscribe(request, listener); } } } diff --git a/app/src/main/kotlin/org/eclipse/kuksa/testapp/KuksaDataBrokerActivity.kt b/app/src/main/kotlin/org/eclipse/kuksa/testapp/KuksaDataBrokerActivity.kt index bfe65513..0e16a4aa 100644 --- a/app/src/main/kotlin/org/eclipse/kuksa/testapp/KuksaDataBrokerActivity.kt +++ b/app/src/main/kotlin/org/eclipse/kuksa/testapp/KuksaDataBrokerActivity.kt @@ -31,7 +31,7 @@ import androidx.compose.ui.Modifier import androidx.lifecycle.lifecycleScope import org.eclipse.kuksa.connectivity.databroker.DataBrokerConnection import org.eclipse.kuksa.connectivity.databroker.listener.DisconnectListener -import org.eclipse.kuksa.connectivity.databroker.listener.PropertyListener +import org.eclipse.kuksa.connectivity.databroker.listener.VssPathListener import org.eclipse.kuksa.connectivity.databroker.listener.VssNodeListener import org.eclipse.kuksa.connectivity.databroker.request.FetchRequest import org.eclipse.kuksa.connectivity.databroker.request.SubscribeRequest @@ -98,9 +98,9 @@ class KuksaDataBrokerActivity : ComponentActivity() { outputViewModel.addOutputEntry("DataBroker disconnected") } - private val propertyListener = object : PropertyListener { - override fun onPropertyChanged(entryUpdates: List) { - Log.d(TAG, "onPropertyChanged() called with: updatedValues = $entryUpdates") + private val vssPathListener = object : VssPathListener { + override fun onEntryChanged(entryUpdates: List) { + Log.d(TAG, "onEntryChanged() called with: updatedValues = $entryUpdates") val entries = mutableListOf().apply { add("Updated Entries") @@ -147,12 +147,12 @@ class KuksaDataBrokerActivity : ComponentActivity() { vssPathsViewModel.onSubscribeProperty = { property: DataBrokerProperty -> val request = SubscribeRequest(property.vssPath, *property.fieldTypes.toTypedArray()) - dataBrokerEngine.subscribe(request, propertyListener) + dataBrokerEngine.subscribe(request, vssPathListener) } vssPathsViewModel.onUnsubscribeProperty = { property: DataBrokerProperty -> val request = SubscribeRequest(property.vssPath, *property.fieldTypes.toTypedArray()) - dataBrokerEngine.unsubscribe(request, propertyListener) + dataBrokerEngine.unsubscribe(request, vssPathListener) } } diff --git a/app/src/main/kotlin/org/eclipse/kuksa/testapp/databroker/DataBrokerEngine.kt b/app/src/main/kotlin/org/eclipse/kuksa/testapp/databroker/DataBrokerEngine.kt index 67c0b06d..ae19ab1c 100644 --- a/app/src/main/kotlin/org/eclipse/kuksa/testapp/databroker/DataBrokerEngine.kt +++ b/app/src/main/kotlin/org/eclipse/kuksa/testapp/databroker/DataBrokerEngine.kt @@ -22,7 +22,7 @@ package org.eclipse.kuksa.testapp.databroker import android.content.Context import org.eclipse.kuksa.connectivity.databroker.DataBrokerConnection import org.eclipse.kuksa.connectivity.databroker.listener.DisconnectListener -import org.eclipse.kuksa.connectivity.databroker.listener.PropertyListener +import org.eclipse.kuksa.connectivity.databroker.listener.VssPathListener import org.eclipse.kuksa.connectivity.databroker.listener.VssNodeListener import org.eclipse.kuksa.connectivity.databroker.request.FetchRequest import org.eclipse.kuksa.connectivity.databroker.request.SubscribeRequest @@ -57,9 +57,9 @@ interface DataBrokerEngine { callback: CoroutineCallback, ) - fun subscribe(request: SubscribeRequest, propertyListener: PropertyListener) + fun subscribe(request: SubscribeRequest, listener: VssPathListener) - fun unsubscribe(request: SubscribeRequest, propertyListener: PropertyListener) + fun unsubscribe(request: SubscribeRequest, listener: VssPathListener) fun subscribe( request: VssNodeSubscribeRequest, diff --git a/app/src/main/kotlin/org/eclipse/kuksa/testapp/databroker/KotlinDataBrokerEngine.kt b/app/src/main/kotlin/org/eclipse/kuksa/testapp/databroker/KotlinDataBrokerEngine.kt index 31f4298a..cef18085 100644 --- a/app/src/main/kotlin/org/eclipse/kuksa/testapp/databroker/KotlinDataBrokerEngine.kt +++ b/app/src/main/kotlin/org/eclipse/kuksa/testapp/databroker/KotlinDataBrokerEngine.kt @@ -26,7 +26,7 @@ import org.eclipse.kuksa.connectivity.databroker.DataBrokerConnection import org.eclipse.kuksa.connectivity.databroker.DataBrokerConnector import org.eclipse.kuksa.connectivity.databroker.DataBrokerException import org.eclipse.kuksa.connectivity.databroker.listener.DisconnectListener -import org.eclipse.kuksa.connectivity.databroker.listener.PropertyListener +import org.eclipse.kuksa.connectivity.databroker.listener.VssPathListener import org.eclipse.kuksa.connectivity.databroker.listener.VssNodeListener import org.eclipse.kuksa.connectivity.databroker.request.FetchRequest import org.eclipse.kuksa.connectivity.databroker.request.SubscribeRequest @@ -110,12 +110,12 @@ class KotlinDataBrokerEngine( } } - override fun subscribe(request: SubscribeRequest, propertyListener: PropertyListener) { - dataBrokerConnection?.subscribe(request, propertyListener) + override fun subscribe(request: SubscribeRequest, listener: VssPathListener) { + dataBrokerConnection?.subscribe(request, listener) } - override fun unsubscribe(request: SubscribeRequest, propertyListener: PropertyListener) { - dataBrokerConnection?.unsubscribe(request, propertyListener) + override fun unsubscribe(request: SubscribeRequest, listener: VssPathListener) { + dataBrokerConnection?.unsubscribe(request, listener) } override fun subscribe( diff --git a/docs/QUICKSTART.md b/docs/QUICKSTART.md index 4d627edc..2d06fb6f 100644 --- a/docs/QUICKSTART.md +++ b/docs/QUICKSTART.md @@ -80,18 +80,18 @@ fun update() { lifecycleScope.launch { val request = UpdateRequest("Vehicle.Speed", setOf(Field.FIELD_VALUE)) val datapoint = Datapoint.newBuilder().setFloat(100f).build() - dataBrokerConnection?.update(property, datapoint) + dataBrokerConnection?.update(request, datapoint) } } fun subscribe() { val request = SubscribeRequest("Vehicle.Speed", setOf(Field.FIELD_VALUE)) - val propertyListener = object : PropertyListener { - override fun onPropertyChanged(entryUpdates: List) { + val listener = object : VssPathListener { + override fun onEntryChanged(entryUpdates: List) { entryUpdates.forEach { entryUpdate -> val updatedValue = entryUpdate.entry - // handle property change + // handle entry change when (updatedValue.path) { "Vehicle.Speed" -> { val speed = updatedValue.value.float @@ -100,7 +100,7 @@ fun subscribe() { } } - dataBrokerConnection?.subscribe(request, propertyListener) + dataBrokerConnection?.subscribe(request, listener) } ``` *Java* @@ -131,13 +131,13 @@ void update() { void subscribe() { SubscribeRequest request = new SubscribeRequest("Vehicle.Speed", Collections.singleton(Types.Field.FIELD_VALUE)); - dataBrokerConnection.subscribe(request, new PropertyListener() { + dataBrokerConnection.subscribe(request, new VssPathListener() { @Override - public void onPropertyChanged(@NonNull List entryUpdates) { + public void onEntryChanged(@NonNull List entryUpdates) { for (KuksaValV1.EntryUpdate entryUpdate : entryUpdates) { Types.DataEntry updatedValue = entryUpdate.getEntry(); - // handle property change + // handle entry change switch (updatedValue.getPath()) { case "Vehicle.Speed": float speed = updatedValue.getValue().getFloat(); @@ -152,11 +152,12 @@ void subscribe() { } ``` -## VSS Symbol Processing +## VSS Model Generation -The generic nature of using the `Property` API will result into an information loss of the type which can be seen in -the `subscribe` example. You may choose to reuse the same listener for multiple properties. Then it requires an additional check -of the `vssPath` after receiving an updated value to correctly cast it back. This is feasible for simple use cases but can get tedious when working with a lot of vehicle signals. +The generic nature of using the `VSS Path` API will result into an information loss of the type which can be seen in +the `subscribe` example. You may choose to reuse the same listener for multiple VSS paths. Then it requires an additional check +of the `vssPath` after receiving an updated value to correctly cast it back. This is feasible for simple use cases but can get tedious +when working with a lot of vehicle signals. For a more convenient usage you can opt in to auto generate Kotlin models via [Symbol Processing](https://kotlinlang.org/docs/ksp-quickstart.html) of the same specification the Databroker uses. For starters you can retrieve an extensive default specification from the diff --git a/docs/kuksa-sdk_class-diagram.puml b/docs/kuksa-sdk_class-diagram.puml index 2f48b935..95303d93 100644 --- a/docs/kuksa-sdk_class-diagram.puml +++ b/docs/kuksa-sdk_class-diagram.puml @@ -26,8 +26,7 @@ package kuksa { DataBrokerConnector -down-> DataBrokerConnection DataBrokerConnection -down-> DataBrokerTransporter DataBrokerConnection -down-> DataBrokerSubscriber - DataBrokerConnection -down-> PropertyListener - DataBrokerConnection -down-> Property + DataBrokerConnection -down-> VssPathListener DataBrokerConnection -left-> DataBrokerException DataBrokerConnection -up-> MultiListener DataBrokerSubscriber -up-> DataBrokerTransporter @@ -53,9 +52,9 @@ package kuksa { } class DataBrokerSubscriber { - + subscribe(vssPath: String, Field, PropertyListener) + + subscribe(vssPath: String, Field, VssPathListener) + subscribe(T, Field, VssNodeListener) - + unsubscribe(vssPath: String, Field, PropertyListener) + + unsubscribe(vssPath: String, Field, VssPathListener) + unsubscribe(T, Field, VssNodeListener) } @@ -63,25 +62,44 @@ package kuksa { + disconnectListeners: MultiListener + jsonWebToken: JsonWebToken - + subscribe(Property, PropertyListener) - + subscribe(T, Collection, VssNodeListener) - + unsubscribe(Property, PropertyListener) - + unsubscribe(T, Collection, VssNodeListener) - + fetch(Property): GetResponse - + fetch(T, Collection) - + update(Property, Datapoint): SetResponse - + update(VssNode, Collection): SetResponse + + subscribe(SubscribeRequest, VssPathListener) + + subscribe(VssNodeSubscribeRequest, VssNodeListener) + + unsubscribe(SubscribeRequest, VssPathListener) + + unsubscribe(VssNodeSubscribeRequest, VssNodeListener) + + fetch(FetchRequest): GetResponse + + fetch(VssNodeFetchRequest) + + update(UpdateRequest): SetResponse + + update(VssNodeUpdateRequest): SetResponse + disconnect() } - interface PropertyListener { - + onPropertyChanged(List) + interface VssPathListener { + + onEntryChanged(List) + onError(Throwable) } - class Property { - + vssPath: String - + fields: Collection + package request { + interface DataBrokerRequest { + + vssPath: String + + fields: Array + } + + class UpdateRequest { + + dataPoint: Datapoint + } + + class VssNodeDataBrokerRequest { + + vssNode: T + } + + DataBrokerRequest <|-- FetchRequest + DataBrokerRequest <|-- SubscribeRequest + DataBrokerRequest <|-- UpdateRequest + DataBrokerRequest <|-- VssNodeDataBrokerRequest + + VssNodeDataBrokerRequest <|-- VssNodeFetchRequest + VssNodeDataBrokerRequest <|-- VssNodeSubscribeRequest + VssNodeDataBrokerRequest <|-- VssNodeUpdateRequest } class DataBrokerException @@ -103,5 +121,6 @@ package kuksa { DataBrokerConnector -up-> ManagedChannel DataBrokerConnection -right-> proto +DataBrokerConnection -right-> request @enduml diff --git a/kuksa-sdk/src/main/kotlin/org/eclipse/kuksa/connectivity/databroker/DataBrokerConnection.kt b/kuksa-sdk/src/main/kotlin/org/eclipse/kuksa/connectivity/databroker/DataBrokerConnection.kt index 1e451b86..1b4cbc70 100644 --- a/kuksa-sdk/src/main/kotlin/org/eclipse/kuksa/connectivity/databroker/DataBrokerConnection.kt +++ b/kuksa-sdk/src/main/kotlin/org/eclipse/kuksa/connectivity/databroker/DataBrokerConnection.kt @@ -26,8 +26,8 @@ import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.withContext import org.eclipse.kuksa.connectivity.authentication.JsonWebToken import org.eclipse.kuksa.connectivity.databroker.listener.DisconnectListener -import org.eclipse.kuksa.connectivity.databroker.listener.PropertyListener import org.eclipse.kuksa.connectivity.databroker.listener.VssNodeListener +import org.eclipse.kuksa.connectivity.databroker.listener.VssPathListener import org.eclipse.kuksa.connectivity.databroker.request.FetchRequest import org.eclipse.kuksa.connectivity.databroker.request.SubscribeRequest import org.eclipse.kuksa.connectivity.databroker.request.UpdateRequest @@ -91,30 +91,30 @@ class DataBrokerConnection internal constructor( } /** - * Subscribes to the specified [request] and notifies the provided [propertyListener] about updates. + * Subscribes to the specified [request] and notifies the provided [listener] about updates. * * Throws a [DataBrokerException] in case the connection to the DataBroker is no longer active */ fun subscribe( request: SubscribeRequest, - propertyListener: PropertyListener, + listener: VssPathListener, ) { val vssPath = request.vssPath request.fields.forEach { field -> - dataBrokerSubscriber.subscribe(vssPath, field, propertyListener) + dataBrokerSubscriber.subscribe(vssPath, field, listener) } } /** - * Unsubscribes the [propertyListener] from updates of the specified [request]. + * Unsubscribes the [listener] from updates of the specified [request]. */ fun unsubscribe( request: SubscribeRequest, - propertyListener: PropertyListener, + listener: VssPathListener, ) { val vssPath = request.vssPath request.fields.forEach { field -> - dataBrokerSubscriber.unsubscribe(vssPath, field, propertyListener) + dataBrokerSubscriber.unsubscribe(vssPath, field, listener) } } @@ -155,12 +155,13 @@ class DataBrokerConnection internal constructor( } /** - * Retrieves the underlying property of the specified vssPath and returns it to the corresponding Callback. + * Retrieves the underlying data broker information of the specified vssPath and returns it to the corresponding + * callback. * * @throws DataBrokerException in case the connection to the DataBroker is no longer active */ suspend fun fetch(request: FetchRequest): GetResponse { - Log.d(TAG, "fetchProperty() called with: property: $request") + Log.d(TAG, "Fetching via request: $request") return dataBrokerTransporter.fetch(request.vssPath, *request.fields) } @@ -206,7 +207,7 @@ class DataBrokerConnection internal constructor( * @throws DataBrokerException in case the connection to the DataBroker is no longer active */ suspend fun update(request: UpdateRequest): SetResponse { - Log.d(TAG, "updateProperty() called with: updatedProperty = $request") + Log.d(TAG, "Update with request: $request") return dataBrokerTransporter.update(request.vssPath, request.dataPoint, *request.fields) } @@ -225,8 +226,9 @@ class DataBrokerConnection internal constructor( val vssNode = request.vssNode vssNode.vssLeafs.forEach { vssLeaf -> - val property = UpdateRequest(vssLeaf.vssPath, vssLeaf.datapoint, *request.fields) - val response = update(property) + val simpleUpdateRequest = UpdateRequest(vssLeaf.vssPath, vssLeaf.datapoint, *request.fields) + val response = update(simpleUpdateRequest) + responses.add(response) } diff --git a/kuksa-sdk/src/main/kotlin/org/eclipse/kuksa/connectivity/databroker/DataBrokerTransporter.kt b/kuksa-sdk/src/main/kotlin/org/eclipse/kuksa/connectivity/databroker/DataBrokerTransporter.kt index 9016c217..fac7754f 100644 --- a/kuksa-sdk/src/main/kotlin/org/eclipse/kuksa/connectivity/databroker/DataBrokerTransporter.kt +++ b/kuksa-sdk/src/main/kotlin/org/eclipse/kuksa/connectivity/databroker/DataBrokerTransporter.kt @@ -161,7 +161,7 @@ internal class DataBrokerTransporter( val streamObserver = object : StreamObserver { override fun onNext(value: SubscribeResponse) { subscription.listeners.forEach { observer -> - observer.onPropertyChanged(value.updatesList) + observer.onEntryChanged(value.updatesList) } subscription.lastSubscribeResponse = value diff --git a/kuksa-sdk/src/main/kotlin/org/eclipse/kuksa/connectivity/databroker/listener/PropertyListener.kt b/kuksa-sdk/src/main/kotlin/org/eclipse/kuksa/connectivity/databroker/listener/VssPathListener.kt similarity index 94% rename from kuksa-sdk/src/main/kotlin/org/eclipse/kuksa/connectivity/databroker/listener/PropertyListener.kt rename to kuksa-sdk/src/main/kotlin/org/eclipse/kuksa/connectivity/databroker/listener/VssPathListener.kt index bde17974..83f69c0e 100644 --- a/kuksa-sdk/src/main/kotlin/org/eclipse/kuksa/connectivity/databroker/listener/PropertyListener.kt +++ b/kuksa-sdk/src/main/kotlin/org/eclipse/kuksa/connectivity/databroker/listener/VssPathListener.kt @@ -27,11 +27,11 @@ import org.eclipse.kuksa.vsscore.model.VssNode * listener to e.g. Vehicle.ADAS.ABS this listener will also be notified about changes of the children * Vehicle.ADAS.ABS.IsEnabled or Vehicle.ADAS.ABS.IsEngaged. */ -interface PropertyListener : Listener { +interface VssPathListener : Listener { /** * Will be triggered with a list of [entryUpdates] of the corresponding field. */ - fun onPropertyChanged(entryUpdates: List) + fun onEntryChanged(entryUpdates: List) /** * Will be triggered when an error happens during subscription and forwards the [throwable]. diff --git a/kuksa-sdk/src/main/kotlin/org/eclipse/kuksa/connectivity/databroker/request/SubscribeRequest.kt b/kuksa-sdk/src/main/kotlin/org/eclipse/kuksa/connectivity/databroker/request/SubscribeRequest.kt index 0a8648f1..f0201598 100644 --- a/kuksa-sdk/src/main/kotlin/org/eclipse/kuksa/connectivity/databroker/request/SubscribeRequest.kt +++ b/kuksa-sdk/src/main/kotlin/org/eclipse/kuksa/connectivity/databroker/request/SubscribeRequest.kt @@ -23,7 +23,7 @@ import org.eclipse.kuksa.proto.v1.Types /** * Used for subscribe requests with [org.eclipse.kuksa.connectivity.databroker.DataBrokerConnection.subscribe]. */ -class SubscribeRequest @JvmOverloads constructor( +open class SubscribeRequest @JvmOverloads constructor( override val vssPath: String, override vararg val fields: Types.Field = arrayOf(Types.Field.FIELD_VALUE), ) : DataBrokerRequest diff --git a/kuksa-sdk/src/main/kotlin/org/eclipse/kuksa/connectivity/databroker/request/UpdateRequest.kt b/kuksa-sdk/src/main/kotlin/org/eclipse/kuksa/connectivity/databroker/request/UpdateRequest.kt index dab8acea..310b6c4e 100644 --- a/kuksa-sdk/src/main/kotlin/org/eclipse/kuksa/connectivity/databroker/request/UpdateRequest.kt +++ b/kuksa-sdk/src/main/kotlin/org/eclipse/kuksa/connectivity/databroker/request/UpdateRequest.kt @@ -24,7 +24,7 @@ import org.eclipse.kuksa.proto.v1.Types.Datapoint /** * Used for update requests with [org.eclipse.kuksa.connectivity.databroker.DataBrokerConnection.update]. */ -class UpdateRequest @JvmOverloads constructor( +open class UpdateRequest @JvmOverloads constructor( override val vssPath: String, val dataPoint: Datapoint, override vararg val fields: Types.Field = arrayOf(Types.Field.FIELD_VALUE), diff --git a/kuksa-sdk/src/main/kotlin/org/eclipse/kuksa/connectivity/databroker/request/VssNodeFetchRequest.kt b/kuksa-sdk/src/main/kotlin/org/eclipse/kuksa/connectivity/databroker/request/VssNodeFetchRequest.kt index bd42e83c..10fac153 100644 --- a/kuksa-sdk/src/main/kotlin/org/eclipse/kuksa/connectivity/databroker/request/VssNodeFetchRequest.kt +++ b/kuksa-sdk/src/main/kotlin/org/eclipse/kuksa/connectivity/databroker/request/VssNodeFetchRequest.kt @@ -29,4 +29,7 @@ import org.eclipse.kuksa.vsscore.model.VssNode class VssNodeFetchRequest @JvmOverloads constructor( override val vssNode: T, override vararg val fields: Types.Field = arrayOf(Types.Field.FIELD_VALUE), -) : VssNodeDataBrokerRequest, FetchRequest(vssNode.vssPath, *fields) +) : VssNodeDataBrokerRequest { + override val vssPath: String + get() = vssNode.vssPath +} diff --git a/kuksa-sdk/src/main/kotlin/org/eclipse/kuksa/connectivity/databroker/request/VssNodeSubscribeRequest.kt b/kuksa-sdk/src/main/kotlin/org/eclipse/kuksa/connectivity/databroker/request/VssNodeSubscribeRequest.kt index 8e7e6c16..b0eff496 100644 --- a/kuksa-sdk/src/main/kotlin/org/eclipse/kuksa/connectivity/databroker/request/VssNodeSubscribeRequest.kt +++ b/kuksa-sdk/src/main/kotlin/org/eclipse/kuksa/connectivity/databroker/request/VssNodeSubscribeRequest.kt @@ -29,4 +29,7 @@ import org.eclipse.kuksa.vsscore.model.VssNode class VssNodeSubscribeRequest @JvmOverloads constructor( override val vssNode: T, override vararg val fields: Types.Field = arrayOf(Types.Field.FIELD_VALUE), -) : VssNodeDataBrokerRequest, FetchRequest(vssNode.vssPath, *fields) +) : VssNodeDataBrokerRequest { + override val vssPath: String + get() = vssNode.vssPath +} diff --git a/kuksa-sdk/src/main/kotlin/org/eclipse/kuksa/connectivity/databroker/request/VssNodeUpdateRequest.kt b/kuksa-sdk/src/main/kotlin/org/eclipse/kuksa/connectivity/databroker/request/VssNodeUpdateRequest.kt index 2c9a105f..687ccc0f 100644 --- a/kuksa-sdk/src/main/kotlin/org/eclipse/kuksa/connectivity/databroker/request/VssNodeUpdateRequest.kt +++ b/kuksa-sdk/src/main/kotlin/org/eclipse/kuksa/connectivity/databroker/request/VssNodeUpdateRequest.kt @@ -29,4 +29,7 @@ import org.eclipse.kuksa.vsscore.model.VssNode class VssNodeUpdateRequest @JvmOverloads constructor( override val vssNode: T, override vararg val fields: Types.Field = arrayOf(Types.Field.FIELD_VALUE), -) : VssNodeDataBrokerRequest, FetchRequest(vssNode.vssPath, *fields) +) : VssNodeDataBrokerRequest { + override val vssPath: String + get() = vssNode.vssPath +} diff --git a/kuksa-sdk/src/main/kotlin/org/eclipse/kuksa/connectivity/databroker/subscription/DataBrokerSubscriber.kt b/kuksa-sdk/src/main/kotlin/org/eclipse/kuksa/connectivity/databroker/subscription/DataBrokerSubscriber.kt index 0e43d7b9..c615c0f6 100644 --- a/kuksa-sdk/src/main/kotlin/org/eclipse/kuksa/connectivity/databroker/subscription/DataBrokerSubscriber.kt +++ b/kuksa-sdk/src/main/kotlin/org/eclipse/kuksa/connectivity/databroker/subscription/DataBrokerSubscriber.kt @@ -21,8 +21,8 @@ package org.eclipse.kuksa.connectivity.databroker.subscription import android.util.Log import org.eclipse.kuksa.connectivity.databroker.DataBrokerException import org.eclipse.kuksa.connectivity.databroker.DataBrokerTransporter -import org.eclipse.kuksa.connectivity.databroker.listener.PropertyListener import org.eclipse.kuksa.connectivity.databroker.listener.VssNodeListener +import org.eclipse.kuksa.connectivity.databroker.listener.VssPathListener import org.eclipse.kuksa.extension.TAG import org.eclipse.kuksa.proto.v1.Types import org.eclipse.kuksa.proto.v1.Types.Field @@ -33,7 +33,7 @@ import org.eclipse.kuksa.vsscore.model.VssNode * Creates [DataBrokerSubscription]s to the DataBroker to get notified about changes on the underlying vssPaths and * fields.If no [DataBrokerSubscription] for a given vssPath and field does exist the DataBrokerSubscriber will create * a new one. If it was already requested before, the same [DataBrokerSubscription] will be re-used. When the last - * [PropertyListener] of a [DataBrokerSubscription] unsubscribes the [DataBrokerSubscription] will be automatically + * [VssPathListener] of a [DataBrokerSubscription] unsubscribes the [DataBrokerSubscription] will be automatically * canceled and removed from the active [DataBrokerSubscription]s. */ internal class DataBrokerSubscriber(private val dataBrokerTransporter: DataBrokerTransporter) { @@ -42,10 +42,10 @@ internal class DataBrokerSubscriber(private val dataBrokerTransporter: DataBroke /** * Checks if the SDK is already subscribed to the corresponding [vssPath] and [field], if the SDK is already - * subscribed it will simply add the 3rd-party [propertyListener] to the current subscription. If not, a new - * Subscription is made and the [propertyListener] is added to it. + * subscribed it will simply add the 3rd-party [listener] to the current subscription. If not, a new + * Subscription is made and the [listener] is added to it. */ - fun subscribe(vssPath: String, field: Field, propertyListener: PropertyListener) { + fun subscribe(vssPath: String, field: Field, listener: VssPathListener) { val identifier = createIdentifier(vssPath, field) var subscription = subscriptions[identifier] if (subscription == null) { @@ -54,19 +54,19 @@ internal class DataBrokerSubscriber(private val dataBrokerTransporter: DataBroke Log.v(TAG, "Created $subscription") } - subscription.listeners.register(propertyListener) + subscription.listeners.register(listener) } /** - * Removes the specified [propertyListener] for the specified [vssPath] and [field] from an already existing + * Removes the specified [listener] for the specified [vssPath] and [field] from an already existing * Subscription to the DataBroker. If the given Subscription has no more Listeners after unsubscribing it will be * canceled and removed. Gracefully ignores invalid input, e.g. when a [vssPath] and [field] of a non-subscribed * property is provided. */ - fun unsubscribe(vssPath: String, field: Field, propertyListener: PropertyListener) { + fun unsubscribe(vssPath: String, field: Field, listener: VssPathListener) { val identifier = createIdentifier(vssPath, field) val subscription = subscriptions[identifier] ?: return - subscription.listeners.unregister(propertyListener) + subscription.listeners.unregister(listener) if (subscription.listeners.isEmpty()) { Log.v(TAG, "Removing $subscription: no more listeners") @@ -92,8 +92,8 @@ internal class DataBrokerSubscriber(private val dataBrokerTransporter: DataBroke ) { val vssPath = node.vssPath - val specificationPropertyListener = SpecificationPropertyListener(node, listener) - subscribe(vssPath, field, specificationPropertyListener) + val vssNodePathListener = VssNodePathListener(node, listener) + subscribe(vssPath, field, vssNodePathListener) } /** @@ -109,8 +109,8 @@ internal class DataBrokerSubscriber(private val dataBrokerTransporter: DataBroke ) { val vssPath = node.vssPath - val specificationPropertyListener = SpecificationPropertyListener(node, listener) - unsubscribe(vssPath, field, specificationPropertyListener) + val vssNodePathListener = VssNodePathListener(node, listener) + unsubscribe(vssPath, field, vssNodePathListener) } private companion object { diff --git a/kuksa-sdk/src/main/kotlin/org/eclipse/kuksa/connectivity/databroker/subscription/DataBrokerSubscription.kt b/kuksa-sdk/src/main/kotlin/org/eclipse/kuksa/connectivity/databroker/subscription/DataBrokerSubscription.kt index a099badb..461b737b 100644 --- a/kuksa-sdk/src/main/kotlin/org/eclipse/kuksa/connectivity/databroker/subscription/DataBrokerSubscription.kt +++ b/kuksa-sdk/src/main/kotlin/org/eclipse/kuksa/connectivity/databroker/subscription/DataBrokerSubscription.kt @@ -19,14 +19,14 @@ package org.eclipse.kuksa.connectivity.databroker.subscription import io.grpc.Context -import org.eclipse.kuksa.connectivity.databroker.listener.PropertyListener +import org.eclipse.kuksa.connectivity.databroker.listener.VssPathListener import org.eclipse.kuksa.pattern.listener.MultiListener import org.eclipse.kuksa.proto.v1.KuksaValV1.SubscribeResponse import org.eclipse.kuksa.proto.v1.Types.Field /** * Denotes a Subscription to the DataBroker. Will be notified about changes w.r.t. the specified [vssPath] and [field]. - * To get informed about these changes it is required to register an [PropertyListener] using [listeners]. + * To get informed about these changes it is required to register an [VssPathListener] using [listeners]. * [cancellableContext] is used to cancel the subscription. When the Subscription is canceled the communication channel * to the DataBroker is closed, no more updates will be received from that point on. * @@ -39,7 +39,7 @@ internal class DataBrokerSubscription( val field: Field, private val cancellableContext: Context.CancellableContext, ) { - val listeners: MultiListener = MultiListener( + val listeners: MultiListener = MultiListener( onRegistered = { observer -> // initial update on registration if (lastThrowable != null) { @@ -47,7 +47,7 @@ internal class DataBrokerSubscription( } else { val lastSubscribeResponse = lastSubscribeResponse ?: return@MultiListener - observer.onPropertyChanged(lastSubscribeResponse.updatesList) + observer.onEntryChanged(lastSubscribeResponse.updatesList) } }, ) diff --git a/kuksa-sdk/src/main/kotlin/org/eclipse/kuksa/connectivity/databroker/subscription/SpecificationPropertyListener.kt b/kuksa-sdk/src/main/kotlin/org/eclipse/kuksa/connectivity/databroker/subscription/VssNodePathListener.kt similarity index 86% rename from kuksa-sdk/src/main/kotlin/org/eclipse/kuksa/connectivity/databroker/subscription/SpecificationPropertyListener.kt rename to kuksa-sdk/src/main/kotlin/org/eclipse/kuksa/connectivity/databroker/subscription/VssNodePathListener.kt index 774b49bc..d7a8e8c9 100644 --- a/kuksa-sdk/src/main/kotlin/org/eclipse/kuksa/connectivity/databroker/subscription/SpecificationPropertyListener.kt +++ b/kuksa-sdk/src/main/kotlin/org/eclipse/kuksa/connectivity/databroker/subscription/VssNodePathListener.kt @@ -18,21 +18,21 @@ package org.eclipse.kuksa.connectivity.databroker.subscription -import org.eclipse.kuksa.connectivity.databroker.listener.PropertyListener import org.eclipse.kuksa.connectivity.databroker.listener.VssNodeListener +import org.eclipse.kuksa.connectivity.databroker.listener.VssPathListener import org.eclipse.kuksa.extension.vss.copy import org.eclipse.kuksa.proto.v1.KuksaValV1 import org.eclipse.kuksa.vsscore.model.VssNode -internal class SpecificationPropertyListener( +internal class VssNodePathListener( node: T, private val listener: VssNodeListener, -) : PropertyListener { +) : VssPathListener { // This is currently needed because we get multiple subscribe responses for every heir. Otherwise we // would override the last heir value with every new response. private var updatedVssNode: T = node - override fun onPropertyChanged(entryUpdates: List) { + override fun onEntryChanged(entryUpdates: List) { entryUpdates.forEach { entryUpdate -> val dataEntry = entryUpdate.entry updatedVssNode = updatedVssNode.copy(dataEntry.path, dataEntry.value) @@ -50,7 +50,7 @@ internal class SpecificationPropertyListener( if (this === other) return true if (javaClass != other?.javaClass) return false - other as SpecificationPropertyListener<*> + other as VssNodePathListener<*> return listener == other.listener } diff --git a/kuksa-sdk/src/test/kotlin/org/eclipse/kuksa/connectivity/databroker/DataBrokerConnectionTest.kt b/kuksa-sdk/src/test/kotlin/org/eclipse/kuksa/connectivity/databroker/DataBrokerConnectionTest.kt index 074d4e17..0f237503 100644 --- a/kuksa-sdk/src/test/kotlin/org/eclipse/kuksa/connectivity/databroker/DataBrokerConnectionTest.kt +++ b/kuksa-sdk/src/test/kotlin/org/eclipse/kuksa/connectivity/databroker/DataBrokerConnectionTest.kt @@ -31,7 +31,7 @@ import io.mockk.slot import io.mockk.verify import kotlinx.coroutines.runBlocking import org.eclipse.kuksa.connectivity.databroker.listener.DisconnectListener -import org.eclipse.kuksa.connectivity.databroker.listener.PropertyListener +import org.eclipse.kuksa.connectivity.databroker.listener.VssPathListener import org.eclipse.kuksa.connectivity.databroker.request.FetchRequest import org.eclipse.kuksa.connectivity.databroker.request.SubscribeRequest import org.eclipse.kuksa.connectivity.databroker.request.UpdateRequest @@ -60,13 +60,13 @@ class DataBrokerConnectionTest : BehaviorSpec({ val subscribeRequest = SubscribeRequest(vssPath, field) `when`("Subscribing to the Property") { - val propertyListener = mockk(relaxed = true) - dataBrokerConnection.subscribe(subscribeRequest, propertyListener) + val vssPathListener = mockk(relaxed = true) + dataBrokerConnection.subscribe(subscribeRequest, vssPathListener) then("The #onPropertyChanged method is triggered") { val capturingSlot = slot>() verify(timeout = 100L) { - propertyListener.onPropertyChanged(capture(capturingSlot)) + vssPathListener.onEntryChanged(capture(capturingSlot)) } val entryUpdates = capturingSlot.captured @@ -75,7 +75,7 @@ class DataBrokerConnectionTest : BehaviorSpec({ } `when`("The observed Property changes") { - clearMocks(propertyListener) + clearMocks(vssPathListener) val random = Random(System.currentTimeMillis()) val newValue = random.nextFloat() @@ -87,7 +87,7 @@ class DataBrokerConnectionTest : BehaviorSpec({ val capturingSlot = slot>() verify(timeout = 100) { - propertyListener.onPropertyChanged(capture(capturingSlot)) + vssPathListener.onEntryChanged(capture(capturingSlot)) } val entryUpdates = capturingSlot.captured @@ -228,13 +228,13 @@ class DataBrokerConnectionTest : BehaviorSpec({ val invalidVssPath = "Vehicle.Some.Unknown.Path" `when`("Trying to subscribe to the INVALID Property") { - val propertyListener = mockk(relaxed = true) + val vssPathListener = mockk(relaxed = true) val subscribeRequest = SubscribeRequest(invalidVssPath) - dataBrokerConnection.subscribe(subscribeRequest, propertyListener) + dataBrokerConnection.subscribe(subscribeRequest, vssPathListener) then("The PropertyListener#onError method should be triggered with 'NOT_FOUND' (Path not found)") { val capturingSlot = slot() - verify(timeout = 100L) { propertyListener.onError(capture(capturingSlot)) } + verify(timeout = 100L) { vssPathListener.onError(capture(capturingSlot)) } val capturedThrowable = capturingSlot.captured capturedThrowable.message shouldContain "NOT_FOUND" } diff --git a/kuksa-sdk/src/test/kotlin/org/eclipse/kuksa/connectivity/databroker/DataBrokerTransporterTest.kt b/kuksa-sdk/src/test/kotlin/org/eclipse/kuksa/connectivity/databroker/DataBrokerTransporterTest.kt index 93fd8b1d..f2280888 100644 --- a/kuksa-sdk/src/test/kotlin/org/eclipse/kuksa/connectivity/databroker/DataBrokerTransporterTest.kt +++ b/kuksa-sdk/src/test/kotlin/org/eclipse/kuksa/connectivity/databroker/DataBrokerTransporterTest.kt @@ -25,7 +25,7 @@ import io.kotest.matchers.shouldNotBe import io.kotest.matchers.types.instanceOf import io.mockk.mockk import io.mockk.verify -import org.eclipse.kuksa.connectivity.databroker.listener.PropertyListener +import org.eclipse.kuksa.connectivity.databroker.listener.VssPathListener import org.eclipse.kuksa.extensions.updateRandomFloatValue import org.eclipse.kuksa.proto.v1.KuksaValV1 import org.eclipse.kuksa.proto.v1.Types @@ -101,15 +101,15 @@ class DataBrokerTransporterTest : BehaviorSpec({ `when`("Subscribing to the vssPath using FIELD_VALUE") { val subscription = classUnderTest.subscribe(vssPath, Types.Field.FIELD_VALUE) - val propertyListener = mockk(relaxed = true) - subscription.listeners.register(propertyListener) + val vssPathListener = mockk(relaxed = true) + subscription.listeners.register(vssPathListener) and("The value of the vssPath is updated") { classUnderTest.updateRandomFloatValue(vssPath) then("The PropertyListener should be notified") { verify { - propertyListener.onPropertyChanged(any()) + vssPathListener.onEntryChanged(any()) } } } @@ -118,12 +118,12 @@ class DataBrokerTransporterTest : BehaviorSpec({ `when`("Subscribing to an invalid vssPath") { val subscription = classUnderTest.subscribe("Vehicle.Some.Invalid.Path", Types.Field.FIELD_VALUE) - val propertyListener = mockk(relaxed = true) - subscription.listeners.register(propertyListener) + val vssPathListener = mockk(relaxed = true) + subscription.listeners.register(vssPathListener) then("An Error should be triggered") { verify(timeout = 100L) { - propertyListener.onError(any()) + vssPathListener.onError(any()) } } } diff --git a/kuksa-sdk/src/test/kotlin/org/eclipse/kuksa/connectivity/databroker/subscription/DataBrokerSubscriberTest.kt b/kuksa-sdk/src/test/kotlin/org/eclipse/kuksa/connectivity/databroker/subscription/DataBrokerSubscriberTest.kt index b138473a..522f5fa3 100644 --- a/kuksa-sdk/src/test/kotlin/org/eclipse/kuksa/connectivity/databroker/subscription/DataBrokerSubscriberTest.kt +++ b/kuksa-sdk/src/test/kotlin/org/eclipse/kuksa/connectivity/databroker/subscription/DataBrokerSubscriberTest.kt @@ -29,11 +29,11 @@ import io.mockk.verify import kotlinx.coroutines.delay import org.eclipse.kuksa.connectivity.databroker.DataBrokerConnectorProvider import org.eclipse.kuksa.connectivity.databroker.DataBrokerTransporter -import org.eclipse.kuksa.connectivity.databroker.listener.PropertyListener +import org.eclipse.kuksa.connectivity.databroker.listener.VssPathListener import org.eclipse.kuksa.extensions.toggleBoolean import org.eclipse.kuksa.extensions.updateRandomFloatValue import org.eclipse.kuksa.extensions.updateRandomUint32Value -import org.eclipse.kuksa.mocking.FriendlyPropertyListener +import org.eclipse.kuksa.mocking.FriendlyVssPathListener import org.eclipse.kuksa.mocking.FriendlyVssNodeListener import org.eclipse.kuksa.pattern.listener.MultiListener import org.eclipse.kuksa.pattern.listener.count @@ -61,7 +61,7 @@ class DataBrokerSubscriberTest : BehaviorSpec({ `when`("Subscribing to VSS_PATH (Branch) 'Vehicle.ADAS.ABS'") { val vssPath = "Vehicle.ADAS.ABS" val fieldValue = Types.Field.FIELD_VALUE - val propertyListener = FriendlyPropertyListener() + val propertyListener = FriendlyVssPathListener() classUnderTest.subscribe(vssPath, fieldValue, propertyListener) then("The PropertyListener should send out ONE update containing ALL children") { @@ -108,7 +108,7 @@ class DataBrokerSubscriberTest : BehaviorSpec({ `when`("Subscribing using VSS_PATH to Vehicle.Speed with FIELD_VALUE") { val vssPath = "Vehicle.Speed" val fieldValue = Types.Field.FIELD_VALUE - val propertyListener = FriendlyPropertyListener() + val propertyListener = FriendlyVssPathListener() classUnderTest.subscribe(vssPath, fieldValue, propertyListener) and("When the FIELD_VALUE of Vehicle.Speed is updated") { @@ -163,9 +163,9 @@ class DataBrokerSubscriberTest : BehaviorSpec({ } `when`("Subscribing multiple (different) PropertyListener to $vssPath") { - val friendlyPropertyListeners = mutableListOf() + val friendlyPropertyListeners = mutableListOf() repeat(10) { - val otherPropertyListenerMock = FriendlyPropertyListener() + val otherPropertyListenerMock = FriendlyVssPathListener() friendlyPropertyListeners.add(otherPropertyListenerMock) classUnderTest.subscribe(vssPath, fieldValue, otherPropertyListenerMock) @@ -208,7 +208,7 @@ class DataBrokerSubscriberTest : BehaviorSpec({ `when`("Subscribing the same PropertyListener twice using VSS_PATH to Vehicle.Speed with FIELD_VALUE") { val vssPath = "Vehicle.Speed" val fieldValue = Types.Field.FIELD_VALUE - val friendlyPropertyListener = FriendlyPropertyListener() + val friendlyPropertyListener = FriendlyVssPathListener() classUnderTest.subscribe(vssPath, fieldValue, friendlyPropertyListener) classUnderTest.subscribe(vssPath, fieldValue, friendlyPropertyListener) @@ -286,7 +286,7 @@ class DataBrokerSubscriberTest : BehaviorSpec({ given("An Instance of DataBrokerSubscriber with a mocked DataBrokerTransporter") { val subscriptionMock = mockk(relaxed = true) val dataBrokerTransporterMock = mockk(relaxed = true) - val multiListener = MultiListener() + val multiListener = MultiListener() every { dataBrokerTransporterMock.subscribe(any(), any()) } returns subscriptionMock every { subscriptionMock.listeners } returns multiListener val classUnderTest = DataBrokerSubscriber(dataBrokerTransporterMock) @@ -294,9 +294,9 @@ class DataBrokerSubscriberTest : BehaviorSpec({ `when`("Subscribing for the first time to a vssPath and field") { val vssPath = "Vehicle.Speed" val field = Types.Field.FIELD_VALUE - val propertyListenerMock1 = mockk() - val propertyListenerMock2 = mockk() - classUnderTest.subscribe(vssPath, field, propertyListenerMock1) + val vssPathListenerMock1 = mockk() + val vssPathListenerMock2 = mockk() + classUnderTest.subscribe(vssPath, field, vssPathListenerMock1) then("A new Subscription is created and the PropertyListener is added to the list of Listeners") { verify { @@ -308,7 +308,7 @@ class DataBrokerSubscriberTest : BehaviorSpec({ `when`("Another PropertyListener subscribes to the same vssPath and field") { clearMocks(dataBrokerTransporterMock) - classUnderTest.subscribe(vssPath, field, propertyListenerMock2) + classUnderTest.subscribe(vssPath, field, vssPathListenerMock2) then("No new Subscription is created and the PropertyListener is added to the list of Listeners") { verify(exactly = 0) { @@ -319,7 +319,7 @@ class DataBrokerSubscriberTest : BehaviorSpec({ } `when`("One of two PropertyListeners unsubscribes") { - classUnderTest.unsubscribe(vssPath, field, propertyListenerMock1) + classUnderTest.unsubscribe(vssPath, field, vssPathListenerMock1) then("The Subscription is not canceled") { verify(exactly = 0) { @@ -329,7 +329,7 @@ class DataBrokerSubscriberTest : BehaviorSpec({ } `when`("The last PropertyListener unsubscribes as well") { - classUnderTest.unsubscribe(vssPath, field, propertyListenerMock2) + classUnderTest.unsubscribe(vssPath, field, vssPathListenerMock2) then("There should be no more listeners registered") { multiListener.count() shouldBe 0 diff --git a/kuksa-sdk/src/test/kotlin/org/eclipse/kuksa/mocking/FriendlyPropertyListener.kt b/kuksa-sdk/src/test/kotlin/org/eclipse/kuksa/mocking/FriendlyVssPathListener.kt similarity index 83% rename from kuksa-sdk/src/test/kotlin/org/eclipse/kuksa/mocking/FriendlyPropertyListener.kt rename to kuksa-sdk/src/test/kotlin/org/eclipse/kuksa/mocking/FriendlyVssPathListener.kt index 026653d1..b3354096 100644 --- a/kuksa-sdk/src/test/kotlin/org/eclipse/kuksa/mocking/FriendlyPropertyListener.kt +++ b/kuksa-sdk/src/test/kotlin/org/eclipse/kuksa/mocking/FriendlyVssPathListener.kt @@ -19,13 +19,13 @@ package org.eclipse.kuksa.mocking -import org.eclipse.kuksa.connectivity.databroker.listener.PropertyListener +import org.eclipse.kuksa.connectivity.databroker.listener.VssPathListener import org.eclipse.kuksa.proto.v1.KuksaValV1 -class FriendlyPropertyListener : PropertyListener { +class FriendlyVssPathListener : VssPathListener { val updates = mutableListOf>() val errors = mutableListOf() - override fun onPropertyChanged(entryUpdates: List) { + override fun onEntryChanged(entryUpdates: List) { updates.add(entryUpdates) } diff --git a/samples/src/main/java/com/example/sample/JavaActivity.java b/samples/src/main/java/com/example/sample/JavaActivity.java index 1d0945db..27829d71 100644 --- a/samples/src/main/java/com/example/sample/JavaActivity.java +++ b/samples/src/main/java/com/example/sample/JavaActivity.java @@ -26,7 +26,7 @@ import org.eclipse.kuksa.connectivity.databroker.DataBrokerConnection; import org.eclipse.kuksa.connectivity.databroker.DataBrokerConnector; import org.eclipse.kuksa.connectivity.databroker.listener.DisconnectListener; -import org.eclipse.kuksa.connectivity.databroker.listener.PropertyListener; +import org.eclipse.kuksa.connectivity.databroker.listener.VssPathListener; import org.eclipse.kuksa.connectivity.databroker.listener.VssNodeListener; import org.eclipse.kuksa.connectivity.databroker.request.FetchRequest; import org.eclipse.kuksa.connectivity.databroker.request.SubscribeRequest; @@ -180,9 +180,9 @@ public void subscribeProperty() { if (dataBrokerConnection == null) return; SubscribeRequest request = new SubscribeRequest("Vehicle.Speed", Types.Field.FIELD_VALUE); - dataBrokerConnection.subscribe(request, new PropertyListener() { + dataBrokerConnection.subscribe(request, new VssPathListener() { @Override - public void onPropertyChanged(@NonNull List entryUpdates) { + public void onEntryChanged(@NonNull List entryUpdates) { for (KuksaValV1.EntryUpdate entryUpdate : entryUpdates) { Types.DataEntry updatedValue = entryUpdate.getEntry(); diff --git a/samples/src/main/kotlin/com/example/sample/KotlinActivity.kt b/samples/src/main/kotlin/com/example/sample/KotlinActivity.kt index bd740e2f..d1cc1576 100644 --- a/samples/src/main/kotlin/com/example/sample/KotlinActivity.kt +++ b/samples/src/main/kotlin/com/example/sample/KotlinActivity.kt @@ -31,7 +31,7 @@ import org.eclipse.kuksa.connectivity.databroker.DataBrokerConnection import org.eclipse.kuksa.connectivity.databroker.DataBrokerConnector import org.eclipse.kuksa.connectivity.databroker.DataBrokerException import org.eclipse.kuksa.connectivity.databroker.listener.DisconnectListener -import org.eclipse.kuksa.connectivity.databroker.listener.PropertyListener +import org.eclipse.kuksa.connectivity.databroker.listener.VssPathListener import org.eclipse.kuksa.connectivity.databroker.listener.VssNodeListener import org.eclipse.kuksa.connectivity.databroker.request.FetchRequest import org.eclipse.kuksa.connectivity.databroker.request.SubscribeRequest @@ -148,8 +148,8 @@ class KotlinActivity : AppCompatActivity() { fun subscribeProperty() { val request = SubscribeRequest("Vehicle.Speed", Types.Field.FIELD_VALUE) - val propertyListener = object : PropertyListener { - override fun onPropertyChanged(entryUpdates: List) { + val vssPathListener = object : VssPathListener { + override fun onEntryChanged(entryUpdates: List) { entryUpdates.forEach { entryUpdate -> val updatedValue = entryUpdate.entry @@ -167,7 +167,7 @@ class KotlinActivity : AppCompatActivity() { } } - dataBrokerConnection?.subscribe(request, propertyListener) + dataBrokerConnection?.subscribe(request, vssPathListener) } // region: VSS generated models From db3ed59bfac11342b5c5fb9726b677b6934846cc Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mark=20Hu=CC=88sers?= Date: Wed, 6 Mar 2024 13:35:07 +0100 Subject: [PATCH 12/20] test: Adapt test naming --- .../kuksa/testapp/KuksaDataBrokerActivity.kt | 2 +- .../testapp/databroker/DataBrokerEngine.kt | 2 +- .../databroker/KotlinDataBrokerEngine.kt | 2 +- .../databroker/DataBrokerConnectionTest.kt | 47 +++++----- .../databroker/DataBrokerTransporterTest.kt | 7 +- .../subscription/DataBrokerSubscriberTest.kt | 94 +++++++++---------- .../kuksa/mocking/FriendlyVssNodeListener.kt | 1 + .../kotlin/org/integration-tests-guide.md | 14 +-- .../com/example/sample/KotlinActivity.kt | 6 +- .../kuksa/vsscore/model/VssNodeTest.kt | 4 +- 10 files changed, 93 insertions(+), 86 deletions(-) diff --git a/app/src/main/kotlin/org/eclipse/kuksa/testapp/KuksaDataBrokerActivity.kt b/app/src/main/kotlin/org/eclipse/kuksa/testapp/KuksaDataBrokerActivity.kt index 0e16a4aa..875ee95f 100644 --- a/app/src/main/kotlin/org/eclipse/kuksa/testapp/KuksaDataBrokerActivity.kt +++ b/app/src/main/kotlin/org/eclipse/kuksa/testapp/KuksaDataBrokerActivity.kt @@ -31,8 +31,8 @@ import androidx.compose.ui.Modifier import androidx.lifecycle.lifecycleScope import org.eclipse.kuksa.connectivity.databroker.DataBrokerConnection import org.eclipse.kuksa.connectivity.databroker.listener.DisconnectListener -import org.eclipse.kuksa.connectivity.databroker.listener.VssPathListener import org.eclipse.kuksa.connectivity.databroker.listener.VssNodeListener +import org.eclipse.kuksa.connectivity.databroker.listener.VssPathListener import org.eclipse.kuksa.connectivity.databroker.request.FetchRequest import org.eclipse.kuksa.connectivity.databroker.request.SubscribeRequest import org.eclipse.kuksa.connectivity.databroker.request.UpdateRequest diff --git a/app/src/main/kotlin/org/eclipse/kuksa/testapp/databroker/DataBrokerEngine.kt b/app/src/main/kotlin/org/eclipse/kuksa/testapp/databroker/DataBrokerEngine.kt index ae19ab1c..7a4547cf 100644 --- a/app/src/main/kotlin/org/eclipse/kuksa/testapp/databroker/DataBrokerEngine.kt +++ b/app/src/main/kotlin/org/eclipse/kuksa/testapp/databroker/DataBrokerEngine.kt @@ -22,8 +22,8 @@ package org.eclipse.kuksa.testapp.databroker import android.content.Context import org.eclipse.kuksa.connectivity.databroker.DataBrokerConnection import org.eclipse.kuksa.connectivity.databroker.listener.DisconnectListener -import org.eclipse.kuksa.connectivity.databroker.listener.VssPathListener import org.eclipse.kuksa.connectivity.databroker.listener.VssNodeListener +import org.eclipse.kuksa.connectivity.databroker.listener.VssPathListener import org.eclipse.kuksa.connectivity.databroker.request.FetchRequest import org.eclipse.kuksa.connectivity.databroker.request.SubscribeRequest import org.eclipse.kuksa.connectivity.databroker.request.UpdateRequest diff --git a/app/src/main/kotlin/org/eclipse/kuksa/testapp/databroker/KotlinDataBrokerEngine.kt b/app/src/main/kotlin/org/eclipse/kuksa/testapp/databroker/KotlinDataBrokerEngine.kt index cef18085..6791eef2 100644 --- a/app/src/main/kotlin/org/eclipse/kuksa/testapp/databroker/KotlinDataBrokerEngine.kt +++ b/app/src/main/kotlin/org/eclipse/kuksa/testapp/databroker/KotlinDataBrokerEngine.kt @@ -26,8 +26,8 @@ import org.eclipse.kuksa.connectivity.databroker.DataBrokerConnection import org.eclipse.kuksa.connectivity.databroker.DataBrokerConnector import org.eclipse.kuksa.connectivity.databroker.DataBrokerException import org.eclipse.kuksa.connectivity.databroker.listener.DisconnectListener -import org.eclipse.kuksa.connectivity.databroker.listener.VssPathListener import org.eclipse.kuksa.connectivity.databroker.listener.VssNodeListener +import org.eclipse.kuksa.connectivity.databroker.listener.VssPathListener import org.eclipse.kuksa.connectivity.databroker.request.FetchRequest import org.eclipse.kuksa.connectivity.databroker.request.SubscribeRequest import org.eclipse.kuksa.connectivity.databroker.request.UpdateRequest diff --git a/kuksa-sdk/src/test/kotlin/org/eclipse/kuksa/connectivity/databroker/DataBrokerConnectionTest.kt b/kuksa-sdk/src/test/kotlin/org/eclipse/kuksa/connectivity/databroker/DataBrokerConnectionTest.kt index 0f237503..a667b9eb 100644 --- a/kuksa-sdk/src/test/kotlin/org/eclipse/kuksa/connectivity/databroker/DataBrokerConnectionTest.kt +++ b/kuksa-sdk/src/test/kotlin/org/eclipse/kuksa/connectivity/databroker/DataBrokerConnectionTest.kt @@ -37,7 +37,6 @@ import org.eclipse.kuksa.connectivity.databroker.request.SubscribeRequest import org.eclipse.kuksa.connectivity.databroker.request.UpdateRequest import org.eclipse.kuksa.connectivity.databroker.request.VssNodeFetchRequest import org.eclipse.kuksa.connectivity.databroker.request.VssNodeSubscribeRequest -import org.eclipse.kuksa.connectivity.databroker.request.VssNodeUpdateRequest import org.eclipse.kuksa.mocking.FriendlyVssNodeListener import org.eclipse.kuksa.proto.v1.KuksaValV1 import org.eclipse.kuksa.proto.v1.Types @@ -59,11 +58,11 @@ class DataBrokerConnectionTest : BehaviorSpec({ val field = Types.Field.FIELD_VALUE val subscribeRequest = SubscribeRequest(vssPath, field) - `when`("Subscribing to the Property") { + `when`("Subscribing to the VSS path") { val vssPathListener = mockk(relaxed = true) dataBrokerConnection.subscribe(subscribeRequest, vssPathListener) - then("The #onPropertyChanged method is triggered") { + then("The #onEntryChanged method is triggered") { val capturingSlot = slot>() verify(timeout = 100L) { vssPathListener.onEntryChanged(capture(capturingSlot)) @@ -74,7 +73,7 @@ class DataBrokerConnectionTest : BehaviorSpec({ entryUpdates[0].entry.path shouldBe vssPath } - `when`("The observed Property changes") { + `when`("The observed VSS path changes") { clearMocks(vssPathListener) val random = Random(System.currentTimeMillis()) @@ -83,7 +82,7 @@ class DataBrokerConnectionTest : BehaviorSpec({ val updateRequest = UpdateRequest(vssPath, datapoint, field) dataBrokerConnection.update(updateRequest) - then("The #onPropertyChanged callback is triggered with the new value") { + then("The #onEntryChanged callback is triggered with the new value") { val capturingSlot = slot>() verify(timeout = 100) { @@ -100,7 +99,7 @@ class DataBrokerConnectionTest : BehaviorSpec({ } val validDatapoint = createRandomFloatDatapoint() - `when`("Updating the Property with a valid Datapoint") { + `when`("Updating the DataBroker property (VSS path) with a valid Datapoint") { // make sure that the value is set and known to us val updateRequest = UpdateRequest(vssPath, validDatapoint, field) val response = dataBrokerConnection.update(updateRequest) @@ -122,7 +121,7 @@ class DataBrokerConnectionTest : BehaviorSpec({ } } - `when`("Updating the Property with a Datapoint of a wrong/different type") { + `when`("Updating the DataBroker property (VSS path) with a Datapoint of a wrong/different type") { val datapoint = createRandomIntDatapoint() val updateRequest = UpdateRequest(vssPath, datapoint) val response = dataBrokerConnection.update(updateRequest) @@ -165,7 +164,7 @@ class DataBrokerConnectionTest : BehaviorSpec({ val fetchRequest = VssNodeFetchRequest(vssDriver) val updatedDriver = dataBrokerConnection.fetch(fetchRequest) - then("Every child property has been updated with the correct value") { + then("Every child node has been updated with the correct value") { val heartRate = updatedDriver.heartRate heartRate.value shouldBe newHeartRateValue @@ -174,29 +173,29 @@ class DataBrokerConnectionTest : BehaviorSpec({ } `when`("Subscribing to the node") { - val specificationListener = FriendlyVssNodeListener() + val vssNodeListener = FriendlyVssNodeListener() val subscribeRequest = VssNodeSubscribeRequest(vssDriver) - dataBrokerConnection.subscribe(subscribeRequest, listener = specificationListener) + dataBrokerConnection.subscribe(subscribeRequest, listener = vssNodeListener) then("The #onSpecificationChanged method is triggered") { eventually(1.seconds) { - specificationListener.updatedSpecifications.size shouldBe 1 + vssNodeListener.updatedSpecifications.size shouldBe 1 } } and("The initial value is different from the default for a child") { val newHeartRateValue = 70 - val newHeartRateVssNode = vssDriver.heartRate.copy(value = newHeartRateValue) - val updateRequest = VssNodeUpdateRequest(newHeartRateVssNode) + val datapoint = Types.Datapoint.newBuilder().setUint32(newHeartRateValue).build() + val updateRequest = UpdateRequest(vssDriver.heartRate.vssPath, datapoint) dataBrokerConnection.update(updateRequest) then("Every child node has been updated with the correct value") { eventually(1.seconds) { - specificationListener.updatedSpecifications.size shouldBe 2 + vssNodeListener.updatedSpecifications.size shouldBe 2 } - val updatedDriver = specificationListener.updatedSpecifications.last() + val updatedDriver = vssNodeListener.updatedSpecifications.last() val heartRate = updatedDriver.heartRate heartRate.value shouldBe newHeartRateValue @@ -205,17 +204,17 @@ class DataBrokerConnectionTest : BehaviorSpec({ and("Any subscribed node was changed") { val newHeartRateValue = 50 - val newHeartRateVssNode = vssDriver.heartRate.copy(value = newHeartRateValue) - val updateRequest = VssNodeUpdateRequest(newHeartRateVssNode) + val datapoint = Types.Datapoint.newBuilder().setUint32(newHeartRateValue).build() + val updateRequest = UpdateRequest(vssDriver.heartRate.vssPath, datapoint) dataBrokerConnection.update(updateRequest) then("The subscribed vssNode should be updated") { eventually(1.seconds) { - specificationListener.updatedSpecifications.size shouldBe 3 + vssNodeListener.updatedSpecifications.size shouldBe 3 } - val updatedDriver = specificationListener.updatedSpecifications.last() + val updatedDriver = vssNodeListener.updatedSpecifications.last() val heartRate = updatedDriver.heartRate heartRate.value shouldBe newHeartRateValue @@ -224,15 +223,15 @@ class DataBrokerConnectionTest : BehaviorSpec({ } } - and("A Property with an INVALID VSS Path") { + and("An INVALID VSS Path") { val invalidVssPath = "Vehicle.Some.Unknown.Path" - `when`("Trying to subscribe to the INVALID Property") { + `when`("Trying to subscribe to the INVALID VSS path") { val vssPathListener = mockk(relaxed = true) val subscribeRequest = SubscribeRequest(invalidVssPath) dataBrokerConnection.subscribe(subscribeRequest, vssPathListener) - then("The PropertyListener#onError method should be triggered with 'NOT_FOUND' (Path not found)") { + then("The VssPathListener#onError method should be triggered with 'NOT_FOUND' (Path not found)") { val capturingSlot = slot() verify(timeout = 100L) { vssPathListener.onError(capture(capturingSlot)) } val capturedThrowable = capturingSlot.captured @@ -240,7 +239,7 @@ class DataBrokerConnectionTest : BehaviorSpec({ } } - `when`("Trying to update the INVALID property") { + `when`("Trying to update the INVALID VSS Path") { // make sure that the value is set and known to us val datapoint = createRandomFloatDatapoint() val updateRequest = UpdateRequest(invalidVssPath, datapoint) @@ -256,7 +255,7 @@ class DataBrokerConnectionTest : BehaviorSpec({ } } - `when`("Trying to fetch the INVALID property") { + `when`("Trying to fetch the INVALID VSS path") { val fetchRequest = FetchRequest(invalidVssPath) val response = dataBrokerConnection.fetch(fetchRequest) diff --git a/kuksa-sdk/src/test/kotlin/org/eclipse/kuksa/connectivity/databroker/DataBrokerTransporterTest.kt b/kuksa-sdk/src/test/kotlin/org/eclipse/kuksa/connectivity/databroker/DataBrokerTransporterTest.kt index f2280888..3088aaa9 100644 --- a/kuksa-sdk/src/test/kotlin/org/eclipse/kuksa/connectivity/databroker/DataBrokerTransporterTest.kt +++ b/kuksa-sdk/src/test/kotlin/org/eclipse/kuksa/connectivity/databroker/DataBrokerTransporterTest.kt @@ -107,7 +107,7 @@ class DataBrokerTransporterTest : BehaviorSpec({ and("The value of the vssPath is updated") { classUnderTest.updateRandomFloatValue(vssPath) - then("The PropertyListener should be notified") { + then("The listener should be notified") { verify { vssPathListener.onEntryChanged(any()) } @@ -116,7 +116,10 @@ class DataBrokerTransporterTest : BehaviorSpec({ } `when`("Subscribing to an invalid vssPath") { - val subscription = classUnderTest.subscribe("Vehicle.Some.Invalid.Path", Types.Field.FIELD_VALUE) + val subscription = classUnderTest.subscribe( + "Vehicle.Some.Invalid.Path", + Types.Field.FIELD_VALUE, + ) val vssPathListener = mockk(relaxed = true) subscription.listeners.register(vssPathListener) diff --git a/kuksa-sdk/src/test/kotlin/org/eclipse/kuksa/connectivity/databroker/subscription/DataBrokerSubscriberTest.kt b/kuksa-sdk/src/test/kotlin/org/eclipse/kuksa/connectivity/databroker/subscription/DataBrokerSubscriberTest.kt index 522f5fa3..4503db13 100644 --- a/kuksa-sdk/src/test/kotlin/org/eclipse/kuksa/connectivity/databroker/subscription/DataBrokerSubscriberTest.kt +++ b/kuksa-sdk/src/test/kotlin/org/eclipse/kuksa/connectivity/databroker/subscription/DataBrokerSubscriberTest.kt @@ -33,8 +33,8 @@ import org.eclipse.kuksa.connectivity.databroker.listener.VssPathListener import org.eclipse.kuksa.extensions.toggleBoolean import org.eclipse.kuksa.extensions.updateRandomFloatValue import org.eclipse.kuksa.extensions.updateRandomUint32Value -import org.eclipse.kuksa.mocking.FriendlyVssPathListener import org.eclipse.kuksa.mocking.FriendlyVssNodeListener +import org.eclipse.kuksa.mocking.FriendlyVssPathListener import org.eclipse.kuksa.pattern.listener.MultiListener import org.eclipse.kuksa.pattern.listener.count import org.eclipse.kuksa.proto.v1.Types @@ -61,34 +61,34 @@ class DataBrokerSubscriberTest : BehaviorSpec({ `when`("Subscribing to VSS_PATH (Branch) 'Vehicle.ADAS.ABS'") { val vssPath = "Vehicle.ADAS.ABS" val fieldValue = Types.Field.FIELD_VALUE - val propertyListener = FriendlyVssPathListener() - classUnderTest.subscribe(vssPath, fieldValue, propertyListener) + val vssPathListener = FriendlyVssPathListener() + classUnderTest.subscribe(vssPath, fieldValue, vssPathListener) - then("The PropertyListener should send out ONE update containing ALL children") { + then("The VssPathListener should send out ONE update containing ALL children") { eventually(1.seconds) { - propertyListener.updates.size shouldBe 1 + vssPathListener.updates.size shouldBe 1 } - val entryUpdates = propertyListener.updates[0] - propertyListener.updates.size shouldBe 1 // ONE update + val entryUpdates = vssPathListener.updates[0] + vssPathListener.updates.size shouldBe 1 // ONE update entryUpdates.size shouldBe 3 // all children: IsEnabled, IsEngaged, IsError entryUpdates.all { it.entry.path.startsWith(vssPath) } shouldBe true } `when`("Any child changes it's value") { - propertyListener.reset() + vssPathListener.reset() val vssPathIsError = "Vehicle.ADAS.ABS.IsError" val newValueIsError = databrokerTransporter.toggleBoolean(vssPathIsError) val vssPathIsEngaged = "Vehicle.ADAS.ABS.IsEngaged" val newValueIsEngaged = databrokerTransporter.toggleBoolean(vssPathIsEngaged) - then("The PropertyListener should be notified about it") { + then("The VssPathListener should be notified about it") { eventually(1.seconds) { - propertyListener.updates.size shouldBe 2 + vssPathListener.updates.size shouldBe 2 } - val entryUpdates = propertyListener.updates.flatten() + val entryUpdates = vssPathListener.updates.flatten() entryUpdates.count { val path = it.entry.path val entry = it.entry @@ -108,31 +108,31 @@ class DataBrokerSubscriberTest : BehaviorSpec({ `when`("Subscribing using VSS_PATH to Vehicle.Speed with FIELD_VALUE") { val vssPath = "Vehicle.Speed" val fieldValue = Types.Field.FIELD_VALUE - val propertyListener = FriendlyVssPathListener() - classUnderTest.subscribe(vssPath, fieldValue, propertyListener) + val vssPathListener = FriendlyVssPathListener() + classUnderTest.subscribe(vssPath, fieldValue, vssPathListener) and("When the FIELD_VALUE of Vehicle.Speed is updated") { val updateRandomFloatValue = databrokerTransporter.updateRandomFloatValue(vssPath) - then("The PropertyListener is notified about the change") { + then("The VssPathListener is notified about the change") { eventually(1.seconds) { - propertyListener.updates.size shouldBe 2 + vssPathListener.updates.size shouldBe 2 } - propertyListener.updates.flatten() + vssPathListener.updates.flatten() .count { val dataEntry = it.entry val datapoint = dataEntry.value dataEntry.path == vssPath && datapoint.float == updateRandomFloatValue } shouldBe 1 - propertyListener.updates.clear() + vssPathListener.updates.clear() } } - `when`("Subscribing the same PropertyListener to a different vssPath") { + `when`("Subscribing the same VssPathListener to a different vssPath") { val otherVssPath = "Vehicle.ADAS.CruiseControl.SpeedSet" - classUnderTest.subscribe(otherVssPath, fieldValue, propertyListener) + classUnderTest.subscribe(otherVssPath, fieldValue, vssPathListener) and("Both values are updated") { val updatedValueVssPath = databrokerTransporter.updateRandomFloatValue(vssPath) @@ -140,10 +140,10 @@ class DataBrokerSubscriberTest : BehaviorSpec({ then("The Observer is notified about both changes") { eventually(1.seconds) { - propertyListener.updates.size shouldBe 3 // 1 from subscribe(otherVssPath) + 2 updates + vssPathListener.updates.size shouldBe 3 // 1 from subscribe(otherVssPath) + 2 updates } - val entryUpdates = propertyListener.updates.flatten() + val entryUpdates = vssPathListener.updates.flatten() entryUpdates .count { val path = it.entry.path @@ -162,25 +162,25 @@ class DataBrokerSubscriberTest : BehaviorSpec({ } } - `when`("Subscribing multiple (different) PropertyListener to $vssPath") { - val friendlyPropertyListeners = mutableListOf() + `when`("Subscribing multiple (different) VssPathListener to $vssPath") { + val friendlyVssPathListeners = mutableListOf() repeat(10) { - val otherPropertyListenerMock = FriendlyVssPathListener() - friendlyPropertyListeners.add(otherPropertyListenerMock) + val otherVssPathListenerMock = FriendlyVssPathListener() + friendlyVssPathListeners.add(otherVssPathListenerMock) - classUnderTest.subscribe(vssPath, fieldValue, otherPropertyListenerMock) + classUnderTest.subscribe(vssPath, fieldValue, otherVssPathListenerMock) } and("When the FIELD_VALUE of Vehicle.Speed is updated") { val randomFloatValue = databrokerTransporter.updateRandomFloatValue(vssPath) - then("Each PropertyListener is only notified once") { - friendlyPropertyListeners.forEach { friendlyPropertyListener -> + then("Each VssPathListener is only notified once") { + friendlyVssPathListeners.forEach { listener -> eventually(1.seconds) { - friendlyPropertyListener.updates.size shouldBe 2 + listener.updates.size shouldBe 2 } - val count = friendlyPropertyListener.updates + val count = listener.updates .count { it[0].entry.value.float == randomFloatValue } count shouldBe 1 } @@ -188,39 +188,39 @@ class DataBrokerSubscriberTest : BehaviorSpec({ } } - `when`("Unsubscribing the previously registered PropertyListener") { - propertyListener.reset() - classUnderTest.unsubscribe(vssPath, fieldValue, propertyListener) + `when`("Unsubscribing the previously registered VssPathListener") { + vssPathListener.reset() + classUnderTest.unsubscribe(vssPath, fieldValue, vssPathListener) and("When the FIELD_VALUE of Vehicle.Speed is updated") { databrokerTransporter.updateRandomFloatValue(vssPath) delay(100) - then("The PropertyListener is not notified") { + then("The VssPathListener is not notified") { continually(100.milliseconds) { - propertyListener.updates.size shouldBe 0 + vssPathListener.updates.size shouldBe 0 } } } } } - `when`("Subscribing the same PropertyListener twice using VSS_PATH to Vehicle.Speed with FIELD_VALUE") { + `when`("Subscribing the same VssPathListener twice using VSS_PATH to Vehicle.Speed with FIELD_VALUE") { val vssPath = "Vehicle.Speed" val fieldValue = Types.Field.FIELD_VALUE - val friendlyPropertyListener = FriendlyVssPathListener() - classUnderTest.subscribe(vssPath, fieldValue, friendlyPropertyListener) - classUnderTest.subscribe(vssPath, fieldValue, friendlyPropertyListener) + val vssPathListener = FriendlyVssPathListener() + classUnderTest.subscribe(vssPath, fieldValue, vssPathListener) + classUnderTest.subscribe(vssPath, fieldValue, vssPathListener) and("When the FIELD_VALUE of Vehicle.Speed is updated") { val randomFloatValue = databrokerTransporter.updateRandomFloatValue(vssPath) - then("The PropertyListener is only notified once") { + then("The VssPathListener is only notified once") { eventually(1.seconds) { - friendlyPropertyListener.updates.size shouldBe 2 + vssPathListener.updates.size shouldBe 2 } - val count = friendlyPropertyListener.updates + val count = vssPathListener.updates .count { it[0].entry.value.float == randomFloatValue } count shouldBe 1 } @@ -298,19 +298,19 @@ class DataBrokerSubscriberTest : BehaviorSpec({ val vssPathListenerMock2 = mockk() classUnderTest.subscribe(vssPath, field, vssPathListenerMock1) - then("A new Subscription is created and the PropertyListener is added to the list of Listeners") { + then("A new Subscription is created and the VssPathListener is added to the list of Listeners") { verify { dataBrokerTransporterMock.subscribe(vssPath, field) } multiListener.count() shouldBe 1 } - `when`("Another PropertyListener subscribes to the same vssPath and field") { + `when`("Another VssPathListener subscribes to the same vssPath and field") { clearMocks(dataBrokerTransporterMock) classUnderTest.subscribe(vssPath, field, vssPathListenerMock2) - then("No new Subscription is created and the PropertyListener is added to the list of Listeners") { + then("No new Subscription is created and the VssPathListener is added to the list of Listeners") { verify(exactly = 0) { dataBrokerTransporterMock.subscribe(vssPath, field) } @@ -318,7 +318,7 @@ class DataBrokerSubscriberTest : BehaviorSpec({ } } - `when`("One of two PropertyListeners unsubscribes") { + `when`("One of two VssPathListeners unsubscribes") { classUnderTest.unsubscribe(vssPath, field, vssPathListenerMock1) then("The Subscription is not canceled") { @@ -328,7 +328,7 @@ class DataBrokerSubscriberTest : BehaviorSpec({ multiListener.count() shouldBe 1 } - `when`("The last PropertyListener unsubscribes as well") { + `when`("The last VssPathListener unsubscribes as well") { classUnderTest.unsubscribe(vssPath, field, vssPathListenerMock2) then("There should be no more listeners registered") { diff --git a/kuksa-sdk/src/test/kotlin/org/eclipse/kuksa/mocking/FriendlyVssNodeListener.kt b/kuksa-sdk/src/test/kotlin/org/eclipse/kuksa/mocking/FriendlyVssNodeListener.kt index 66c88b19..d9d204d2 100644 --- a/kuksa-sdk/src/test/kotlin/org/eclipse/kuksa/mocking/FriendlyVssNodeListener.kt +++ b/kuksa-sdk/src/test/kotlin/org/eclipse/kuksa/mocking/FriendlyVssNodeListener.kt @@ -25,6 +25,7 @@ import org.eclipse.kuksa.vsscore.model.VssNode class FriendlyVssNodeListener : VssNodeListener { val updatedSpecifications = mutableListOf() val errors = mutableListOf() + override fun onNodeChanged(vssNode: T) { updatedSpecifications.add(vssNode) } diff --git a/kuksa-sdk/src/test/kotlin/org/integration-tests-guide.md b/kuksa-sdk/src/test/kotlin/org/integration-tests-guide.md index ed2f35e3..a3b6a904 100644 --- a/kuksa-sdk/src/test/kotlin/org/integration-tests-guide.md +++ b/kuksa-sdk/src/test/kotlin/org/integration-tests-guide.md @@ -3,14 +3,15 @@ corresponding SubscriptionChannels run asynchronously. Between the update execut here and the propagation to the subscribed observers a small timeframe may pass. Therefore things like this most likely won't work because of the behavior described above: ``` - subscribe("Vehicle.Speed", observer) + val request = SubscribeRequest("Vehicle.Speed") + subscribe(request, observer) updateRandomFloatValue("Vehicle.Speed") - verify { observer.onPropertyChanged("Vehicle.Speed", any())} + verify { observer.onEntryChanged("Vehicle.Speed", any())} ``` Keep in mind, that when calling DataBrokerConnection#subscribe an initial update with the current value is send, to the subscribing observer, meaning that checking for a successful update requires at least two calls to the -#onPropertyChanged method. One for the initial update and one for the consecutive, real update of the value. +#onEntryChanged method. One for the initial update and one for the consecutive, real update of the value. Using verify(timeout = 100\[, exactly = 1\]) alone won't fix this issue, because "exactly = 1" will always be fulfilled by the initial update mentioned above. It therefore needs to be something like @@ -18,13 +19,14 @@ verify(timeout = 100, exactly = 2) if an update is expected. A better example therefore would be: ``` - subscribe("Vehicle.Speed", observer) // triggers first #onPropertyChanged with initial value - val value = updateRandomFloatValue() // triggers second #onPropertyChanged with updated value + val request = SubscribeRequest("Vehicle.Speed") + subscribe(request, observer) // triggers first #onEntryChanged with initial value + val value = updateRandomFloatValue() // triggers second #onEntryChanged with updated value val dataEntries = mutableListOf() verify (timeout = 100, exactly = 2) { // initial update + "updateRandomFloatValue") - observer.onPropertyChanged("Vehicle.Speed", capture(dataEntries)) + observer.onEntryChanged("Vehicle.Speed", capture(dataEntries)) } val count = dataEntries.count { it.value.float == randomFloatValue } diff --git a/samples/src/main/kotlin/com/example/sample/KotlinActivity.kt b/samples/src/main/kotlin/com/example/sample/KotlinActivity.kt index d1cc1576..68b1fe9f 100644 --- a/samples/src/main/kotlin/com/example/sample/KotlinActivity.kt +++ b/samples/src/main/kotlin/com/example/sample/KotlinActivity.kt @@ -31,8 +31,8 @@ import org.eclipse.kuksa.connectivity.databroker.DataBrokerConnection import org.eclipse.kuksa.connectivity.databroker.DataBrokerConnector import org.eclipse.kuksa.connectivity.databroker.DataBrokerException import org.eclipse.kuksa.connectivity.databroker.listener.DisconnectListener -import org.eclipse.kuksa.connectivity.databroker.listener.VssPathListener import org.eclipse.kuksa.connectivity.databroker.listener.VssNodeListener +import org.eclipse.kuksa.connectivity.databroker.listener.VssPathListener import org.eclipse.kuksa.connectivity.databroker.request.FetchRequest import org.eclipse.kuksa.connectivity.databroker.request.SubscribeRequest import org.eclipse.kuksa.connectivity.databroker.request.UpdateRequest @@ -131,9 +131,11 @@ class KotlinActivity : AppCompatActivity() { } } + private val newSpeed = 50f + fun updateProperty() { val datapoint = Datapoint.newBuilder() - .setFloat(50f) + .setFloat(newSpeed) .build() val request = UpdateRequest("Vehicle.Speed", datapoint, Types.Field.FIELD_VALUE) lifecycleScope.launch { diff --git a/vss-core/src/test/kotlin/org/eclipse/kuksa/vsscore/model/VssNodeTest.kt b/vss-core/src/test/kotlin/org/eclipse/kuksa/vsscore/model/VssNodeTest.kt index d064c547..d73d6b68 100644 --- a/vss-core/src/test/kotlin/org/eclipse/kuksa/vsscore/model/VssNodeTest.kt +++ b/vss-core/src/test/kotlin/org/eclipse/kuksa/vsscore/model/VssNodeTest.kt @@ -43,8 +43,8 @@ class VssNodeTest : BehaviorSpec({ } } `when`("finding specific properties") { - val properties = vssVehicle.findProperties(VssDriver.VssHeartRate::class) - then("it should return all VssProperties which fit the class") { + val properties = vssVehicle.findLeaf(VssDriver.VssHeartRate::class) + then("it should return all properties which fit the class") { properties.size shouldBe 2 } } From 3ecbac8738000930c175ac84128471e7b75eb82a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mark=20Hu=CC=88sers?= Date: Wed, 6 Mar 2024 16:11:11 +0100 Subject: [PATCH 13/20] chore: Rename VssNode extensions --- .../eclipse/kuksa/testapp/KuksaDataBrokerActivity.kt | 4 ++-- .../kuksa/testapp/databroker/view/DataBrokerView.kt | 4 ++-- .../org/eclipse/kuksa/vsscore/model/VssNode.kt | 12 ++++++------ 3 files changed, 10 insertions(+), 10 deletions(-) diff --git a/app/src/main/kotlin/org/eclipse/kuksa/testapp/KuksaDataBrokerActivity.kt b/app/src/main/kotlin/org/eclipse/kuksa/testapp/KuksaDataBrokerActivity.kt index 875ee95f..44d5bda7 100644 --- a/app/src/main/kotlin/org/eclipse/kuksa/testapp/KuksaDataBrokerActivity.kt +++ b/app/src/main/kotlin/org/eclipse/kuksa/testapp/KuksaDataBrokerActivity.kt @@ -255,9 +255,9 @@ class KuksaDataBrokerActivity : ComponentActivity() { Log.d(TAG, "Fetched automatic value type from meta data: $automaticValueType") - val vssProperties = vssPathsViewModel.dataBrokerProperty + val dataBrokerProperty = vssPathsViewModel.dataBrokerProperty .copy(valueType = automaticValueType) - vssPathsViewModel.updateDataBrokerProperty(vssProperties) + vssPathsViewModel.updateDataBrokerProperty(dataBrokerProperty) } override fun onError(error: Throwable) { diff --git a/app/src/main/kotlin/org/eclipse/kuksa/testapp/databroker/view/DataBrokerView.kt b/app/src/main/kotlin/org/eclipse/kuksa/testapp/databroker/view/DataBrokerView.kt index 6bfc2476..11bc75e4 100644 --- a/app/src/main/kotlin/org/eclipse/kuksa/testapp/databroker/view/DataBrokerView.kt +++ b/app/src/main/kotlin/org/eclipse/kuksa/testapp/databroker/view/DataBrokerView.kt @@ -102,7 +102,7 @@ val MinimumButtonWidth = 150.dp fun DataBrokerView( topAppBarViewModel: TopAppBarViewModel, connectionViewModel: ConnectionViewModel, - vssPropertiesViewModel: VSSPathsViewModel, + vssPathsViewModel: VSSPathsViewModel, vssNodesViewModel: VssNodesViewModel, outputViewModel: OutputViewModel, ) { @@ -125,7 +125,7 @@ fun DataBrokerView( val dataBrokerMode = topAppBarViewModel.dataBrokerMode if (connectionViewModel.isConnected) { when (dataBrokerMode) { - DataBrokerMode.VSS_PATH -> DataBrokerProperties(vssPropertiesViewModel) + DataBrokerMode.VSS_PATH -> DataBrokerProperties(vssPathsViewModel) DataBrokerMode.VSS_FILE -> DataBrokerVssNodes(vssNodesViewModel) } } diff --git a/vss-core/src/main/kotlin/org/eclipse/kuksa/vsscore/model/VssNode.kt b/vss-core/src/main/kotlin/org/eclipse/kuksa/vsscore/model/VssNode.kt index 6a9fef00..460bf162 100644 --- a/vss-core/src/main/kotlin/org/eclipse/kuksa/vsscore/model/VssNode.kt +++ b/vss-core/src/main/kotlin/org/eclipse/kuksa/vsscore/model/VssNode.kt @@ -33,13 +33,13 @@ interface VssNode { val uuid: String /** - * Defines the path to the property inside the VSS tree structure. + * Defines the path to the [VssNode] inside the VSS tree structure. * Example: Vehicle.Body.Horn.IsActive */ val vssPath: String /** - * Simple description of the property. + * Simple description of the [VssNode]. */ val description: String @@ -209,19 +209,19 @@ fun VssNode.findHeritageLine( } /** - * Finds the given [property] inside the current [VssNode]. + * Finds the given [leaf] inside the current [VssNode]. */ -fun , V : Any> VssNode.findProperty(property: VssLeaf): VssLeaf { +fun , V : Any> VssNode.findLeaf(leaf: VssLeaf): VssLeaf { return heritage .filterIsInstance>() - .first { it.uuid == property.uuid } + .first { it.uuid == leaf.uuid } } /** * Finds all [VssLeaf] which matches the given [KClass.simpleName]. This is useful when multiple nested objects * with the same Name exists but are pretty much the same besides the [VssNode.vssPath] etc. */ -fun , V : Any> VssNode.findProperties(type: KClass): Map> { +fun , V : Any> VssNode.findLeaf(type: KClass): Map> { return heritage .filterIsInstance>() .filter { it::class.simpleName == type.simpleName } From defb3a18faaac36c83ca56d03fbc8af4c69736cf Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mark=20Hu=CC=88sers?= Date: Thu, 7 Mar 2024 15:10:14 +0100 Subject: [PATCH 14/20] chore: Converts varargs -> Collection for performance --- .../kuksa/testapp/KuksaDataBrokerActivity.kt | 4 ++- .../databroker/DataBrokerConnection.kt | 23 ++++++++------- .../databroker/DataBrokerTransporter.kt | 4 +-- .../databroker/request/VssNodeFetchRequest.kt | 1 - .../request/VssNodeSubscribeRequest.kt | 1 - .../request/VssNodeUpdateRequest.kt | 1 - .../extension/vss/VssNodeCopyExtension.kt | 28 +++++++++++++------ 7 files changed, 37 insertions(+), 25 deletions(-) diff --git a/app/src/main/kotlin/org/eclipse/kuksa/testapp/KuksaDataBrokerActivity.kt b/app/src/main/kotlin/org/eclipse/kuksa/testapp/KuksaDataBrokerActivity.kt index 44d5bda7..83040f81 100644 --- a/app/src/main/kotlin/org/eclipse/kuksa/testapp/KuksaDataBrokerActivity.kt +++ b/app/src/main/kotlin/org/eclipse/kuksa/testapp/KuksaDataBrokerActivity.kt @@ -65,7 +65,6 @@ import org.eclipse.kuksa.vss.VssVehicle import org.eclipse.kuksa.vsscore.annotation.VssModelGenerator import org.eclipse.kuksa.vsscore.model.VssNode -@Suppress("performance:SpreadOperator") // API convenience > performance @VssModelGenerator class KuksaDataBrokerActivity : ComponentActivity() { private lateinit var connectionInfoRepository: ConnectionInfoRepository @@ -134,6 +133,7 @@ class KuksaDataBrokerActivity : ComponentActivity() { JavaDataBrokerEngine() } + @Suppress("performance:SpreadOperator") // Neglectable: Field types are 1-2 elements mostly override fun onCreate(savedInstanceState: Bundle?) { fun addVssPathsListeners() { vssPathsViewModel.onGetProperty = { property: DataBrokerProperty -> @@ -267,6 +267,7 @@ class KuksaDataBrokerActivity : ComponentActivity() { ) } + @Suppress("performance:SpreadOperator") // Neglectable: Field types are 1-2 elements mostly private fun fetchProperty(property: DataBrokerProperty) { Log.d(TAG, "Fetch property: $property") @@ -300,6 +301,7 @@ class KuksaDataBrokerActivity : ComponentActivity() { ) } + @Suppress("performance:SpreadOperator") // Neglectable: Field types are 1-2 elements mostly private fun updateProperty(property: DataBrokerProperty, datapoint: Datapoint) { Log.d(TAG, "Update property: $property dataPoint: $datapoint, type: ${datapoint.valueCase}") diff --git a/kuksa-sdk/src/main/kotlin/org/eclipse/kuksa/connectivity/databroker/DataBrokerConnection.kt b/kuksa-sdk/src/main/kotlin/org/eclipse/kuksa/connectivity/databroker/DataBrokerConnection.kt index 1b4cbc70..a0fe92f7 100644 --- a/kuksa-sdk/src/main/kotlin/org/eclipse/kuksa/connectivity/databroker/DataBrokerConnection.kt +++ b/kuksa-sdk/src/main/kotlin/org/eclipse/kuksa/connectivity/databroker/DataBrokerConnection.kt @@ -53,7 +53,6 @@ import kotlin.properties.Delegates * The DataBrokerConnection holds an active connection to the DataBroker. The Connection can be use to interact with the * DataBroker. */ -@Suppress("performance:SpreadOperator") // API convenience > performance class DataBrokerConnection internal constructor( private val managedChannel: ManagedChannel, private val dispatcher: CoroutineDispatcher = Dispatchers.Default, @@ -162,7 +161,7 @@ class DataBrokerConnection internal constructor( */ suspend fun fetch(request: FetchRequest): GetResponse { Log.d(TAG, "Fetching via request: $request") - return dataBrokerTransporter.fetch(request.vssPath, *request.fields) + return dataBrokerTransporter.fetch(request.vssPath, request.fields.toSet()) } /** @@ -171,7 +170,10 @@ class DataBrokerConnection internal constructor( * * @throws DataBrokerException in case the connection to the DataBroker is no longer active */ - @Suppress("exceptions:TooGenericExceptionCaught") // Handling is bundled together + + // SpreadOperator: Neglectable - Field types are 1-2 elements mostly + // TooGenericExceptionCaught: Handling is bundled together + @Suppress("exceptions:TooGenericExceptionCaught", "performance:SpreadOperator") suspend fun fetch(request: VssNodeFetchRequest): T { return withContext(dispatcher) { try { @@ -181,19 +183,19 @@ class DataBrokerConnection internal constructor( val entries = response.entriesList if (entries.isEmpty()) { - Log.w(TAG, "No entries found for fetched specification!") + Log.w(TAG, "No entries found for fetched VssNode!") return@withContext vssNode } - // Update every heir specification + // Update every heir node // TODO: Can be optimized to not replace the whole heritage line for every child entry one by one - var updatedSpecification: T = vssNode - val heritage = updatedSpecification.heritage + var updatedVssNode: T = vssNode + val heritage = updatedVssNode.heritage entries.forEach { entry -> - updatedSpecification = updatedSpecification.copy(entry.path, entry.value, heritage) + updatedVssNode = updatedVssNode.copy(entry.path, entry.value, heritage) } - return@withContext updatedSpecification + return@withContext updatedVssNode } catch (e: Exception) { throw DataBrokerException(e.message, e) } @@ -208,7 +210,7 @@ class DataBrokerConnection internal constructor( */ suspend fun update(request: UpdateRequest): SetResponse { Log.d(TAG, "Update with request: $request") - return dataBrokerTransporter.update(request.vssPath, request.dataPoint, *request.fields) + return dataBrokerTransporter.update(request.vssPath, request.dataPoint, request.fields.toSet()) } /** @@ -221,6 +223,7 @@ class DataBrokerConnection internal constructor( * @throws DataBrokerException in case the connection to the DataBroker is no longer active * @throws IllegalArgumentException if the [VssLeaf] could not be converted to a [Datapoint]. */ + @Suppress("performance:SpreadOperator") // Neglectable: Field types are 1-2 elements mostly suspend fun update(request: VssNodeUpdateRequest): Collection { val responses = mutableListOf() val vssNode = request.vssNode diff --git a/kuksa-sdk/src/main/kotlin/org/eclipse/kuksa/connectivity/databroker/DataBrokerTransporter.kt b/kuksa-sdk/src/main/kotlin/org/eclipse/kuksa/connectivity/databroker/DataBrokerTransporter.kt index fac7754f..5df67882 100644 --- a/kuksa-sdk/src/main/kotlin/org/eclipse/kuksa/connectivity/databroker/DataBrokerTransporter.kt +++ b/kuksa-sdk/src/main/kotlin/org/eclipse/kuksa/connectivity/databroker/DataBrokerTransporter.kt @@ -70,7 +70,7 @@ internal class DataBrokerTransporter( */ suspend fun fetch( vssPath: String, - vararg fields: Field, + fields: Collection, ): KuksaValV1.GetResponse { return withContext(defaultDispatcher) { val blockingStub = VALGrpc.newBlockingStub(managedChannel) @@ -101,7 +101,7 @@ internal class DataBrokerTransporter( suspend fun update( vssPath: String, updatedDatapoint: Types.Datapoint, - vararg fields: Field, + fields: Collection, ): KuksaValV1.SetResponse { return withContext(defaultDispatcher) { val blockingStub = VALGrpc.newBlockingStub(managedChannel) diff --git a/kuksa-sdk/src/main/kotlin/org/eclipse/kuksa/connectivity/databroker/request/VssNodeFetchRequest.kt b/kuksa-sdk/src/main/kotlin/org/eclipse/kuksa/connectivity/databroker/request/VssNodeFetchRequest.kt index 10fac153..6e0f3ab4 100644 --- a/kuksa-sdk/src/main/kotlin/org/eclipse/kuksa/connectivity/databroker/request/VssNodeFetchRequest.kt +++ b/kuksa-sdk/src/main/kotlin/org/eclipse/kuksa/connectivity/databroker/request/VssNodeFetchRequest.kt @@ -25,7 +25,6 @@ import org.eclipse.kuksa.vsscore.model.VssNode * Used for fetch requests with a generated [VssNode] model and * [org.eclipse.kuksa.connectivity.databroker.DataBrokerConnection.fetch]. */ -@Suppress("performance:SpreadOperator") // API convenience > performance class VssNodeFetchRequest @JvmOverloads constructor( override val vssNode: T, override vararg val fields: Types.Field = arrayOf(Types.Field.FIELD_VALUE), diff --git a/kuksa-sdk/src/main/kotlin/org/eclipse/kuksa/connectivity/databroker/request/VssNodeSubscribeRequest.kt b/kuksa-sdk/src/main/kotlin/org/eclipse/kuksa/connectivity/databroker/request/VssNodeSubscribeRequest.kt index b0eff496..76a806a2 100644 --- a/kuksa-sdk/src/main/kotlin/org/eclipse/kuksa/connectivity/databroker/request/VssNodeSubscribeRequest.kt +++ b/kuksa-sdk/src/main/kotlin/org/eclipse/kuksa/connectivity/databroker/request/VssNodeSubscribeRequest.kt @@ -25,7 +25,6 @@ import org.eclipse.kuksa.vsscore.model.VssNode * Used for subscribe requests with a generated [VssNode] model and * [org.eclipse.kuksa.connectivity.databroker.DataBrokerConnection.subscribe]. */ -@Suppress("performance:SpreadOperator") // API convenience > performance class VssNodeSubscribeRequest @JvmOverloads constructor( override val vssNode: T, override vararg val fields: Types.Field = arrayOf(Types.Field.FIELD_VALUE), diff --git a/kuksa-sdk/src/main/kotlin/org/eclipse/kuksa/connectivity/databroker/request/VssNodeUpdateRequest.kt b/kuksa-sdk/src/main/kotlin/org/eclipse/kuksa/connectivity/databroker/request/VssNodeUpdateRequest.kt index 687ccc0f..fb8d69d8 100644 --- a/kuksa-sdk/src/main/kotlin/org/eclipse/kuksa/connectivity/databroker/request/VssNodeUpdateRequest.kt +++ b/kuksa-sdk/src/main/kotlin/org/eclipse/kuksa/connectivity/databroker/request/VssNodeUpdateRequest.kt @@ -25,7 +25,6 @@ import org.eclipse.kuksa.vsscore.model.VssNode * Used for update requests with a generated [VssNode] model and * [org.eclipse.kuksa.connectivity.databroker.DataBrokerConnection.update]. */ -@Suppress("performance:SpreadOperator") // API convenience > performance class VssNodeUpdateRequest @JvmOverloads constructor( override val vssNode: T, override vararg val fields: Types.Field = arrayOf(Types.Field.FIELD_VALUE), diff --git a/kuksa-sdk/src/main/kotlin/org/eclipse/kuksa/extension/vss/VssNodeCopyExtension.kt b/kuksa-sdk/src/main/kotlin/org/eclipse/kuksa/extension/vss/VssNodeCopyExtension.kt index 9f0099e9..d1cfff51 100644 --- a/kuksa-sdk/src/main/kotlin/org/eclipse/kuksa/extension/vss/VssNodeCopyExtension.kt +++ b/kuksa-sdk/src/main/kotlin/org/eclipse/kuksa/extension/vss/VssNodeCopyExtension.kt @@ -49,27 +49,37 @@ import kotlin.reflect.full.memberProperties */ // The suggested method to improve the performance can't be used here because we are already working with a full array. // https://detekt.dev/docs/rules/performance/ -@Suppress("performance:SpreadOperator") -fun T.deepCopy(generation: Int = 0, vararg changedHeritage: VssNode): T { +fun T.deepCopy(generation: Int = 0, changedHeritage: List): T { if (generation == changedHeritage.size) { // Reached the end, use the changed [VssLeaf] return this } - // Create the missing link between this [VssNode] and the given property (node inbetween) + // Create the missing link between this [VssNode] and the given node inbetween var heritageLine = changedHeritage if (changedHeritage.size == 1) { heritageLine = findHeritageLine(changedHeritage.first(), true) - .toTypedArray() + .toList() .ifEmpty { changedHeritage } } val childNode = heritageLine[generation] - val childCopy = childNode.deepCopy(generation + 1, *heritageLine) + val childCopy = childNode.deepCopy(generation + 1, heritageLine) val parameterNameToChild = mapOf(childNode.variableName to childCopy) return copy(parameterNameToChild) } +/** + * Convenience method for [deepCopy] with a [VssNode]. It will return the [VssNode] with the updated + * [VssNode]. + * + * @throws [IllegalArgumentException] if the copied types do not match. + * @throws [NoSuchElementException] if no copy method was found for the class. + */ +fun T.deepCopy(vararg vssNodes: VssNode): T { + return deepCopy(0, vssNodes.toList()) +} + /** * Creates a copy of a [VssLeaf] where the [VssLeaf.value] is changed to the given [Datapoint]. */ @@ -160,10 +170,10 @@ fun T.copy( val updatedVssNode = vssNode.copy(updatedValue) - // Same property with no heirs, no deep copy is needed + // Same node with no heirs, no deep copy is needed if (this.vssPath == updatedVssNode.vssPath) return updatedVssNode as T - return deepCopy(0, updatedVssNode) + return deepCopy(updatedVssNode) } // region Operators @@ -175,8 +185,8 @@ fun T.copy( * @throws [IllegalArgumentException] if the copied types do not match. * @throws [NoSuchElementException] if no copy method was found for the class. */ -operator fun T.invoke(vararg property: VssNode): T { - return deepCopy(0, *property) +operator fun T.invoke(vararg vssNodes: VssNode): T { + return deepCopy(0, vssNodes.toList()) } /** From 25d5447724a7a8a9e43fd1c8f1e1aba9241b1391 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mark=20Hu=CC=88sers?= Date: Thu, 7 Mar 2024 15:10:51 +0100 Subject: [PATCH 15/20] chore: Rename missed Specification -> VssNode --- .../databroker/JavaDataBrokerEngine.java | 4 +- .../extension/compose/DropdownMenuView.kt | 4 +- .../databroker/listener/VssPathListener.kt | 2 +- .../subscription/DataBrokerSubscriber.kt | 4 +- .../subscription/VssNodePathListener.kt | 2 +- .../databroker/DataBrokerConnectionTest.kt | 12 ++--- .../subscription/DataBrokerSubscriberTest.kt | 28 +++++----- .../kuksa/mocking/FriendlyVssNodeListener.kt | 6 +-- .../eclipse/kuksa/vssNode/VssNodeCopyTest.kt | 8 +-- .../java/com/example/sample/JavaActivity.java | 8 +-- .../com/example/sample/KotlinActivity.kt | 2 +- .../eclipse/kuksa/vsscore/model/VssNode.kt | 4 +- .../kuksa/vsscore/model/VssNodeTest.kt | 10 ++-- .../vssprocessor/plugin/VssProcessorPlugin.kt | 4 +- .../VssModelGeneratorProcessor.kt | 18 +++---- .../kuksa/vssprocessor/parser/VssParser.kt | 2 +- .../vssprocessor/parser/YamlVssParser.kt | 12 ++--- .../vssprocessor/spec/VssNodeSpecModel.kt | 54 +++++++++---------- .../vssprocessor/spec/VssNodeSpecModelTest.kt | 14 ++--- 19 files changed, 99 insertions(+), 99 deletions(-) diff --git a/app/src/main/java/org/eclipse/kuksa/testapp/databroker/JavaDataBrokerEngine.java b/app/src/main/java/org/eclipse/kuksa/testapp/databroker/JavaDataBrokerEngine.java index 36c2be9c..920d0098 100644 --- a/app/src/main/java/org/eclipse/kuksa/testapp/databroker/JavaDataBrokerEngine.java +++ b/app/src/main/java/org/eclipse/kuksa/testapp/databroker/JavaDataBrokerEngine.java @@ -92,12 +92,12 @@ public void onError(@NonNull Throwable error) { } @Override - public void fetch(@NonNull FetchRequest property, @NonNull CoroutineCallback callback) { + public void fetch(@NonNull FetchRequest request, @NonNull CoroutineCallback callback) { if (dataBrokerConnection == null) { return; } - dataBrokerConnection.fetch(property, callback); + dataBrokerConnection.fetch(request, callback); } @Override diff --git a/app/src/main/kotlin/org/eclipse/kuksa/testapp/extension/compose/DropdownMenuView.kt b/app/src/main/kotlin/org/eclipse/kuksa/testapp/extension/compose/DropdownMenuView.kt index 85d61e2b..64df411f 100644 --- a/app/src/main/kotlin/org/eclipse/kuksa/testapp/extension/compose/DropdownMenuView.kt +++ b/app/src/main/kotlin/org/eclipse/kuksa/testapp/extension/compose/DropdownMenuView.kt @@ -30,11 +30,11 @@ import androidx.compose.foundation.lazy.LazyColumn import androidx.compose.foundation.lazy.itemsIndexed import androidx.compose.foundation.lazy.rememberLazyListState import androidx.compose.foundation.shape.RoundedCornerShape -import androidx.compose.material3.Divider import androidx.compose.material3.DropdownMenuItem import androidx.compose.material3.ExperimentalMaterial3Api import androidx.compose.material3.ExposedDropdownMenuBox import androidx.compose.material3.ExposedDropdownMenuDefaults +import androidx.compose.material3.HorizontalDivider import androidx.compose.material3.LocalContentColor import androidx.compose.material3.MaterialTheme import androidx.compose.material3.OutlinedTextField @@ -205,7 +205,7 @@ fun LazyDropdownMenu( } if (index < items.lastIndex) { - Divider(modifier = Modifier.padding(horizontal = 16.dp)) + HorizontalDivider(modifier = Modifier.padding(horizontal = 16.dp)) } } } diff --git a/kuksa-sdk/src/main/kotlin/org/eclipse/kuksa/connectivity/databroker/listener/VssPathListener.kt b/kuksa-sdk/src/main/kotlin/org/eclipse/kuksa/connectivity/databroker/listener/VssPathListener.kt index 83f69c0e..90401c0b 100644 --- a/kuksa-sdk/src/main/kotlin/org/eclipse/kuksa/connectivity/databroker/listener/VssPathListener.kt +++ b/kuksa-sdk/src/main/kotlin/org/eclipse/kuksa/connectivity/databroker/listener/VssPathListener.kt @@ -43,7 +43,7 @@ interface VssPathListener : Listener { * The Listener is used to notify about subscribed [VssNode]. If a [VssNode] has children * then [onNodeChanged] will be called on every value change for every children. */ -interface VssNodeListener { +interface VssNodeListener : Listener { /** * Will be triggered with the [vssNode] when the underlying vssPath changed it's value or to inform about * the initial state. diff --git a/kuksa-sdk/src/main/kotlin/org/eclipse/kuksa/connectivity/databroker/subscription/DataBrokerSubscriber.kt b/kuksa-sdk/src/main/kotlin/org/eclipse/kuksa/connectivity/databroker/subscription/DataBrokerSubscriber.kt index c615c0f6..64af55ab 100644 --- a/kuksa-sdk/src/main/kotlin/org/eclipse/kuksa/connectivity/databroker/subscription/DataBrokerSubscriber.kt +++ b/kuksa-sdk/src/main/kotlin/org/eclipse/kuksa/connectivity/databroker/subscription/DataBrokerSubscriber.kt @@ -61,7 +61,7 @@ internal class DataBrokerSubscriber(private val dataBrokerTransporter: DataBroke * Removes the specified [listener] for the specified [vssPath] and [field] from an already existing * Subscription to the DataBroker. If the given Subscription has no more Listeners after unsubscribing it will be * canceled and removed. Gracefully ignores invalid input, e.g. when a [vssPath] and [field] of a non-subscribed - * property is provided. + * [vssPath] is provided. */ fun unsubscribe(vssPath: String, field: Field, listener: VssPathListener) { val identifier = createIdentifier(vssPath, field) @@ -100,7 +100,7 @@ internal class DataBrokerSubscriber(private val dataBrokerTransporter: DataBroke * Removes the specified [listener] for the specified [node] and [field] from an already existing * Subscription to the DataBroker. If the given Subscription has no more Listeners after unsubscribing it will be * canceled and removed. Gracefully ignores invalid input, e.g. when a [node] and [field] of a - * non-subscribed property is provided. + * non-subscribed [VssNode] is provided. */ fun unsubscribe( node: T, diff --git a/kuksa-sdk/src/main/kotlin/org/eclipse/kuksa/connectivity/databroker/subscription/VssNodePathListener.kt b/kuksa-sdk/src/main/kotlin/org/eclipse/kuksa/connectivity/databroker/subscription/VssNodePathListener.kt index d7a8e8c9..afe9ac71 100644 --- a/kuksa-sdk/src/main/kotlin/org/eclipse/kuksa/connectivity/databroker/subscription/VssNodePathListener.kt +++ b/kuksa-sdk/src/main/kotlin/org/eclipse/kuksa/connectivity/databroker/subscription/VssNodePathListener.kt @@ -45,7 +45,7 @@ internal class VssNodePathListener( listener.onError(throwable) } - // Two SpecificationObserverWrapper instances are equal if they have the same observer set! + // Two VssNodeObserverWrapper instances are equal if they have the same observer set! override fun equals(other: Any?): Boolean { if (this === other) return true if (javaClass != other?.javaClass) return false diff --git a/kuksa-sdk/src/test/kotlin/org/eclipse/kuksa/connectivity/databroker/DataBrokerConnectionTest.kt b/kuksa-sdk/src/test/kotlin/org/eclipse/kuksa/connectivity/databroker/DataBrokerConnectionTest.kt index a667b9eb..3a992aa6 100644 --- a/kuksa-sdk/src/test/kotlin/org/eclipse/kuksa/connectivity/databroker/DataBrokerConnectionTest.kt +++ b/kuksa-sdk/src/test/kotlin/org/eclipse/kuksa/connectivity/databroker/DataBrokerConnectionTest.kt @@ -177,9 +177,9 @@ class DataBrokerConnectionTest : BehaviorSpec({ val subscribeRequest = VssNodeSubscribeRequest(vssDriver) dataBrokerConnection.subscribe(subscribeRequest, listener = vssNodeListener) - then("The #onSpecificationChanged method is triggered") { + then("The #onNodeChanged method is triggered") { eventually(1.seconds) { - vssNodeListener.updatedSpecifications.size shouldBe 1 + vssNodeListener.updatedVssNodes.size shouldBe 1 } } @@ -192,10 +192,10 @@ class DataBrokerConnectionTest : BehaviorSpec({ then("Every child node has been updated with the correct value") { eventually(1.seconds) { - vssNodeListener.updatedSpecifications.size shouldBe 2 + vssNodeListener.updatedVssNodes.size shouldBe 2 } - val updatedDriver = vssNodeListener.updatedSpecifications.last() + val updatedDriver = vssNodeListener.updatedVssNodes.last() val heartRate = updatedDriver.heartRate heartRate.value shouldBe newHeartRateValue @@ -211,10 +211,10 @@ class DataBrokerConnectionTest : BehaviorSpec({ then("The subscribed vssNode should be updated") { eventually(1.seconds) { - vssNodeListener.updatedSpecifications.size shouldBe 3 + vssNodeListener.updatedVssNodes.size shouldBe 3 } - val updatedDriver = vssNodeListener.updatedSpecifications.last() + val updatedDriver = vssNodeListener.updatedVssNodes.last() val heartRate = updatedDriver.heartRate heartRate.value shouldBe newHeartRateValue diff --git a/kuksa-sdk/src/test/kotlin/org/eclipse/kuksa/connectivity/databroker/subscription/DataBrokerSubscriberTest.kt b/kuksa-sdk/src/test/kotlin/org/eclipse/kuksa/connectivity/databroker/subscription/DataBrokerSubscriberTest.kt index 4503db13..3c174221 100644 --- a/kuksa-sdk/src/test/kotlin/org/eclipse/kuksa/connectivity/databroker/subscription/DataBrokerSubscriberTest.kt +++ b/kuksa-sdk/src/test/kotlin/org/eclipse/kuksa/connectivity/databroker/subscription/DataBrokerSubscriberTest.kt @@ -227,55 +227,55 @@ class DataBrokerSubscriberTest : BehaviorSpec({ } } - val specification = VssDriver.VssHeartRate() + val vssHeartRate = VssDriver.VssHeartRate() `when`("Subscribing using a VSS node to Vehicle.Driver.HeartRate with Field FIELD_VALUE") { val friendlyVssNodeListener = FriendlyVssNodeListener() classUnderTest.subscribe( - specification, + vssHeartRate, Types.Field.FIELD_VALUE, friendlyVssNodeListener, ) and("The value of Vehicle.Driver.HeartRate changes") { val randomIntValue = - databrokerTransporter.updateRandomUint32Value(specification.vssPath) + databrokerTransporter.updateRandomUint32Value(vssHeartRate.vssPath) then("The Observer should be triggered") { eventually(1.seconds) { - friendlyVssNodeListener.updatedSpecifications.size shouldBe 2 + friendlyVssNodeListener.updatedVssNodes.size shouldBe 2 } - val count = friendlyVssNodeListener.updatedSpecifications + val count = friendlyVssNodeListener.updatedVssNodes .count { it.value == randomIntValue } count shouldBe 1 } } } - `when`("Subscribing the same SpecificationObserver twice to Vehicle.Driver.HeartRate") { - val specificationObserverMock = FriendlyVssNodeListener() + `when`("Subscribing the same VssNodeObserver twice to Vehicle.Driver.HeartRate") { + val nodeListenerMock = FriendlyVssNodeListener() classUnderTest.subscribe( - specification, + vssHeartRate, Types.Field.FIELD_VALUE, - specificationObserverMock, + nodeListenerMock, ) classUnderTest.subscribe( - specification, + vssHeartRate, Types.Field.FIELD_VALUE, - specificationObserverMock, + nodeListenerMock, ) and("The value of Vehicle.Driver.HeartRate changes") { val randomIntValue = - databrokerTransporter.updateRandomUint32Value(specification.vssPath) + databrokerTransporter.updateRandomUint32Value(vssHeartRate.vssPath) then("The Observer is only notified once") { eventually(1.seconds) { - specificationObserverMock.updatedSpecifications.size shouldBe 2 + nodeListenerMock.updatedVssNodes.size shouldBe 2 } - val count = specificationObserverMock.updatedSpecifications.count { it.value == randomIntValue } + val count = nodeListenerMock.updatedVssNodes.count { it.value == randomIntValue } count shouldBe 1 } } diff --git a/kuksa-sdk/src/test/kotlin/org/eclipse/kuksa/mocking/FriendlyVssNodeListener.kt b/kuksa-sdk/src/test/kotlin/org/eclipse/kuksa/mocking/FriendlyVssNodeListener.kt index d9d204d2..ce4c7acb 100644 --- a/kuksa-sdk/src/test/kotlin/org/eclipse/kuksa/mocking/FriendlyVssNodeListener.kt +++ b/kuksa-sdk/src/test/kotlin/org/eclipse/kuksa/mocking/FriendlyVssNodeListener.kt @@ -23,11 +23,11 @@ import org.eclipse.kuksa.connectivity.databroker.listener.VssNodeListener import org.eclipse.kuksa.vsscore.model.VssNode class FriendlyVssNodeListener : VssNodeListener { - val updatedSpecifications = mutableListOf() + val updatedVssNodes = mutableListOf() val errors = mutableListOf() override fun onNodeChanged(vssNode: T) { - updatedSpecifications.add(vssNode) + updatedVssNodes.add(vssNode) } override fun onError(throwable: Throwable) { @@ -35,7 +35,7 @@ class FriendlyVssNodeListener : VssNodeListener { } fun reset() { - updatedSpecifications.clear() + updatedVssNodes.clear() errors.clear() } } diff --git a/kuksa-sdk/src/test/kotlin/org/eclipse/kuksa/vssNode/VssNodeCopyTest.kt b/kuksa-sdk/src/test/kotlin/org/eclipse/kuksa/vssNode/VssNodeCopyTest.kt index ba81c39a..343156b1 100644 --- a/kuksa-sdk/src/test/kotlin/org/eclipse/kuksa/vssNode/VssNodeCopyTest.kt +++ b/kuksa-sdk/src/test/kotlin/org/eclipse/kuksa/vssNode/VssNodeCopyTest.kt @@ -35,7 +35,7 @@ import org.eclipse.kuksa.vsscore.model.VssLeaf class VssNodeCopyTest : BehaviorSpec({ tags(Unit) - given("A specification") { + given("A VssNode") { val vehicle = VssVehicle() val driverHeartRate: VssLeaf = vehicle.driver.heartRate @@ -44,7 +44,7 @@ class VssNodeCopyTest : BehaviorSpec({ val updatedHeartRate = VssDriver.VssHeartRate(value = newValue) `when`("a deep copy is done with a changed heritage line") { - val deepCopiedNode = vehicle.deepCopy(0, updatedHeartRate) + val deepCopiedNode = vehicle.deepCopy(updatedHeartRate) then("it should return the new children as a copy") { val heartRate = deepCopiedNode.driver.heartRate @@ -110,11 +110,11 @@ class VssNodeCopyTest : BehaviorSpec({ val datapoint = Types.Datapoint.newBuilder().build() and("an invalid VssLeaf") { - val invalidSpecification = VssInvalid() + val vssInvalid = VssInvalid() `when`("a copy is done") { val exception = shouldThrow { - invalidSpecification.copy(datapoint) + vssInvalid.copy(datapoint) } then("it should throw an IllegalArgumentException") { diff --git a/samples/src/main/java/com/example/sample/JavaActivity.java b/samples/src/main/java/com/example/sample/JavaActivity.java index 27829d71..1271330f 100644 --- a/samples/src/main/java/com/example/sample/JavaActivity.java +++ b/samples/src/main/java/com/example/sample/JavaActivity.java @@ -139,7 +139,7 @@ public void disconnect() { dataBrokerConnection = null; } - public void fetchProperty() { + public void fetch() { if (dataBrokerConnection == null) return; FetchRequest request = new FetchRequest("Vehicle.Speed", Types.Field.FIELD_VALUE); @@ -156,7 +156,7 @@ public void onError(@NonNull Throwable throwable) { }); } - public void updateProperty() { + public void update() { if (dataBrokerConnection == null) return; Datapoint datapoint = Datapoint.newBuilder() @@ -176,7 +176,7 @@ public void onError(@NonNull Throwable error) { }); } - public void subscribeProperty() { + public void subscribe() { if (dataBrokerConnection == null) return; SubscribeRequest request = new SubscribeRequest("Vehicle.Speed", Types.Field.FIELD_VALUE); @@ -186,7 +186,7 @@ public void onEntryChanged(@NonNull List entryUpdates) { for (KuksaValV1.EntryUpdate entryUpdate : entryUpdates) { Types.DataEntry updatedValue = entryUpdate.getEntry(); - // handle property change + // handle value change //noinspection SwitchStatementWithTooFewBranches switch (updatedValue.getPath()) { case "VSS.Speed": diff --git a/samples/src/main/kotlin/com/example/sample/KotlinActivity.kt b/samples/src/main/kotlin/com/example/sample/KotlinActivity.kt index 68b1fe9f..b1c64fce 100644 --- a/samples/src/main/kotlin/com/example/sample/KotlinActivity.kt +++ b/samples/src/main/kotlin/com/example/sample/KotlinActivity.kt @@ -155,7 +155,7 @@ class KotlinActivity : AppCompatActivity() { entryUpdates.forEach { entryUpdate -> val updatedValue = entryUpdate.entry - // handle property change + // handle value change when (updatedValue.path) { "Vehicle.Speed" -> { val speed = updatedValue.value.float diff --git a/vss-core/src/main/kotlin/org/eclipse/kuksa/vsscore/model/VssNode.kt b/vss-core/src/main/kotlin/org/eclipse/kuksa/vsscore/model/VssNode.kt index 460bf162..6f400198 100644 --- a/vss-core/src/main/kotlin/org/eclipse/kuksa/vsscore/model/VssNode.kt +++ b/vss-core/src/main/kotlin/org/eclipse/kuksa/vsscore/model/VssNode.kt @@ -195,9 +195,9 @@ fun VssNode.findHeritageLine( heir: VssNode, isReplacingHeir: Boolean = false, ): Collection { - val specificationKeys = heir.vssPathHeritageLine + val vssNodeKeys = heir.vssPathHeritageLine val heritageLine = heritage.filter { child -> - specificationKeys.contains(child.vssPath) + vssNodeKeys.contains(child.vssPath) }.toMutableList() if (isReplacingHeir && heritageLine.isNotEmpty()) { diff --git a/vss-core/src/test/kotlin/org/eclipse/kuksa/vsscore/model/VssNodeTest.kt b/vss-core/src/test/kotlin/org/eclipse/kuksa/vsscore/model/VssNodeTest.kt index d73d6b68..b5986301 100644 --- a/vss-core/src/test/kotlin/org/eclipse/kuksa/vsscore/model/VssNodeTest.kt +++ b/vss-core/src/test/kotlin/org/eclipse/kuksa/vsscore/model/VssNodeTest.kt @@ -22,7 +22,7 @@ import io.kotest.core.spec.style.BehaviorSpec import io.kotest.matchers.shouldBe class VssNodeTest : BehaviorSpec({ - given("The root level specification") { + given("The root level VssNode") { val vssVehicle = VssVehicle() `when`("finding the whole heritage") { val heritage = vssVehicle.heritage @@ -42,10 +42,10 @@ class VssNodeTest : BehaviorSpec({ heritageLine shouldBe listOf(vssVehicle.driver, vssVehicle.driver.heartRate) } } - `when`("finding specific properties") { - val properties = vssVehicle.findLeaf(VssDriver.VssHeartRate::class) - then("it should return all properties which fit the class") { - properties.size shouldBe 2 + `when`("finding specific leafs") { + val leafs = vssVehicle.findLeaf(VssDriver.VssHeartRate::class) + then("it should return all leafs which fit the class") { + leafs.size shouldBe 2 } } `when`("getting the variable name") { diff --git a/vss-processor-plugin/src/main/java/org/eclipse/kuksa/vssprocessor/plugin/VssProcessorPlugin.kt b/vss-processor-plugin/src/main/java/org/eclipse/kuksa/vssprocessor/plugin/VssProcessorPlugin.kt index ae307ed4..b2914433 100644 --- a/vss-processor-plugin/src/main/java/org/eclipse/kuksa/vssprocessor/plugin/VssProcessorPlugin.kt +++ b/vss-processor-plugin/src/main/java/org/eclipse/kuksa/vssprocessor/plugin/VssProcessorPlugin.kt @@ -75,7 +75,7 @@ class VssProcessorPlugin : Plugin { .append(KSP_INPUT_BUILD_DIRECTORY) .append(fileSeparator) .toString() - val vssBuildFile = File(vssFilePath) + val vssFile = File(vssFilePath) logger.info("Searching directory $searchPath for VSS definitions") @@ -88,7 +88,7 @@ class VssProcessorPlugin : Plugin { } inputDir.set(searchDir) - outputDir.set(vssBuildFile) + outputDir.set(vssFile) } tasks.getByName("preBuild").dependsOn( diff --git a/vss-processor/src/main/kotlin/org/eclipse/kuksa/vssprocessor/VssModelGeneratorProcessor.kt b/vss-processor/src/main/kotlin/org/eclipse/kuksa/vssprocessor/VssModelGeneratorProcessor.kt index be4cee07..ef8eaccb 100644 --- a/vss-processor/src/main/kotlin/org/eclipse/kuksa/vssprocessor/VssModelGeneratorProcessor.kt +++ b/vss-processor/src/main/kotlin/org/eclipse/kuksa/vssprocessor/VssModelGeneratorProcessor.kt @@ -44,8 +44,8 @@ import org.eclipse.kuksa.vssprocessor.spec.VssPath import java.io.File /** - * Generates a [org.eclipse.kuksa.vsscore.model.VssNode] for every specification listed in the input file. - * These nodes are a usable kotlin data class reflection of the specification. + * Generates a [org.eclipse.kuksa.vsscore.model.VssNode] for every entry listed in the input file. + * These nodes are a usable kotlin data class reflection of the element. * * @param codeGenerator to generate class files with * @param logger to log output with @@ -109,26 +109,26 @@ class VssModelGeneratorProcessor( .toSet() } - private fun generateModelFiles(vssPathToSpecification: Map) { - val duplicateSpecificationNames = vssPathToSpecification.keys + private fun generateModelFiles(vssPathToVssNode: Map) { + val duplicateNodeNames = vssPathToVssNode.keys .groupBy { it.leaf } .filter { it.value.size > 1 } .keys - logger.info("Ambiguous specifications - Generate nested classes: $duplicateSpecificationNames") + logger.info("Ambiguous VssNode - Generate nested classes: $duplicateNodeNames") val generatedFilesVssPathToClassName = mutableMapOf() - for ((vssPath, specModel) in vssPathToSpecification) { + for ((vssPath, specModel) in vssPathToVssNode) { // Every duplicate is produced as a nested class - No separate file should be generated - if (duplicateSpecificationNames.contains(vssPath.leaf)) { + if (duplicateNodeNames.contains(vssPath.leaf)) { continue } specModel.logger = logger val classSpec = specModel.createClassSpec( PACKAGE_NAME, - vssPathToSpecification.values, - duplicateSpecificationNames, + vssPathToVssNode.values, + duplicateNodeNames, ) val className = classSpec.name ?: throw NoSuchFieldException("Class spec $classSpec has no name field!") diff --git a/vss-processor/src/main/kotlin/org/eclipse/kuksa/vssprocessor/parser/VssParser.kt b/vss-processor/src/main/kotlin/org/eclipse/kuksa/vssprocessor/parser/VssParser.kt index 04dcdd0e..a8622eb1 100644 --- a/vss-processor/src/main/kotlin/org/eclipse/kuksa/vssprocessor/parser/VssParser.kt +++ b/vss-processor/src/main/kotlin/org/eclipse/kuksa/vssprocessor/parser/VssParser.kt @@ -25,7 +25,7 @@ import java.io.File internal interface VssParser { /** * @param definitionFile to parse [VssNodeSpecModel] with - * @param elementDelimiter which is the separator string between the specifications. The default is an empty line. + * @param elementDelimiter which is the separator string between the elements. The default is an empty line. */ fun parseNodes( definitionFile: File, diff --git a/vss-processor/src/main/kotlin/org/eclipse/kuksa/vssprocessor/parser/YamlVssParser.kt b/vss-processor/src/main/kotlin/org/eclipse/kuksa/vssprocessor/parser/YamlVssParser.kt index 705cc26d..413e8a9f 100644 --- a/vss-processor/src/main/kotlin/org/eclipse/kuksa/vssprocessor/parser/YamlVssParser.kt +++ b/vss-processor/src/main/kotlin/org/eclipse/kuksa/vssprocessor/parser/YamlVssParser.kt @@ -28,14 +28,14 @@ import kotlin.reflect.full.memberProperties internal class YamlVssParser : VssParser { override fun parseNodes(definitionFile: File, elementDelimiter: String): List { - val specificationElements = mutableListOf() + val vssNodeElements = mutableListOf() definitionFile.useLines { lines -> val yamlAttributes = mutableListOf() for (line in lines.toList()) { val trimmedLine = line.trim() if (trimmedLine == elementDelimiter) { // A new element will follow after the delimiter - parseYamlElement(yamlAttributes)?.let { specificationElement -> - specificationElements.add(specificationElement) + parseYamlElement(yamlAttributes)?.let { vssNodeElement -> + vssNodeElements.add(vssNodeElement) } yamlAttributes.clear() @@ -47,12 +47,12 @@ internal class YamlVssParser : VssParser { } // Add the last element because no empty line will follow - parseYamlElement(yamlAttributes)?.let { specificationElement -> - specificationElements.add(specificationElement) + parseYamlElement(yamlAttributes)?.let { vssNodeElement -> + vssNodeElements.add(vssNodeElement) } } - return specificationElements + return vssNodeElements } // Example .yaml element: diff --git a/vss-processor/src/main/kotlin/org/eclipse/kuksa/vssprocessor/spec/VssNodeSpecModel.kt b/vss-processor/src/main/kotlin/org/eclipse/kuksa/vssprocessor/spec/VssNodeSpecModel.kt index 5f3e497c..32b41792 100644 --- a/vss-processor/src/main/kotlin/org/eclipse/kuksa/vssprocessor/spec/VssNodeSpecModel.kt +++ b/vss-processor/src/main/kotlin/org/eclipse/kuksa/vssprocessor/spec/VssNodeSpecModel.kt @@ -43,8 +43,8 @@ import kotlin.reflect.KClass import kotlin.reflect.KProperty1 import kotlin.reflect.full.declaredMemberProperties -// Reflects the specification file as a model and is filled via reflection. That is why the variable names -// should exactly match the names inside the specification file and be of a string type. +// Reflects the VSS file as a model and is filled via reflection. That is why the variable names +// should exactly match the names inside the VSS file and be of a string type. internal class VssNodeSpecModel( override var uuid: String = "", override var vssPath: String = "", @@ -102,12 +102,12 @@ internal class VssNodeSpecModel( override fun createClassSpec( packageName: String, - relatedSpecifications: Collection, + relatedNodes: Collection, nestedClasses: Collection, ): TypeSpec { - val childSpecifications = relatedSpecifications.filter { it.parentKey == name } + val childNodes = relatedNodes.filter { it.parentKey == name } // Every specification has only one parent, do not check again for heirs - val reducedRelatedSpecifications = relatedSpecifications - childSpecifications.toSet() - this + val reducedRelatedNodes = relatedNodes - childNodes.toSet() - this val nestedChildSpecs = mutableListOf() val constructorBuilder = FunSpec.constructorBuilder() @@ -116,7 +116,7 @@ internal class VssNodeSpecModel( val superInterfaces = mutableSetOf(VssNode::class.asTypeName()) // The last element in the chain should have a value like "isLocked". - if (childSpecifications.isEmpty()) { + if (childNodes.isEmpty()) { val (valuePropertySpec, parameterSpec) = createValueSpec() constructorBuilder.addParameter(parameterSpec) @@ -133,14 +133,14 @@ internal class VssNodeSpecModel( val propertySpec = createVssNodeSpecs(className, packageName = packageName) propertySpecs.addAll(propertySpec) - // Parses all specifications into properties - childSpecifications.forEach { childSpecification -> - // This nested specification has an ambiguous name, add as nested class + // Parses all VssNodes into properties + childNodes.forEach { childNode -> + // This nested node has an ambiguous name, add as nested class // The package name is different for nested classes (no qualifier) - val hasAmbiguousName = nestedClasses.contains(childSpecification.name) + val hasAmbiguousName = nestedClasses.contains(childNode.name) val uniquePackageName = if (hasAmbiguousName) "" else packageName - val childPropertySpec = createVssNodeSpecs(className, uniquePackageName, childSpecification) + val childPropertySpec = createVssNodeSpecs(className, uniquePackageName, childNode) propertySpecs.addAll(childPropertySpec) // Nested VssNode properties should be added as constructor parameters @@ -148,19 +148,19 @@ internal class VssNodeSpecModel( if (mainClassPropertySpec.initializer != null) { // Only add a default for initializer if (hasAmbiguousName) { // All children should contain the prefix vssPath (improves performance) - val relevantRelatedSpecifications = reducedRelatedSpecifications.filter { - it.vssPath.contains(childSpecification.vssPath + ".") + val relevantRelatedNodes = reducedRelatedNodes.filter { + it.vssPath.contains(childNode.vssPath + ".") } - val childSpec = childSpecification.createClassSpec( + val childSpec = childNode.createClassSpec( packageName, - relevantRelatedSpecifications, + relevantRelatedNodes, nestedClasses, ) nestedChildSpecs.add(childSpec) } - val defaultClassName = childSpecification.className + val defaultClassName = childNode.className val defaultParameter = createDefaultParameterSpec( mainClassPropertySpec.name, defaultClassName, @@ -171,7 +171,7 @@ internal class VssNodeSpecModel( } } - val nodeSpecs = createVssNodeTreeSpecs(childSpecifications) + val nodeSpecs = createVssNodeTreeSpecs(childNodes) propertySpecs.addAll(nodeSpecs) val className = ClassName(packageName, className) @@ -213,7 +213,7 @@ internal class VssNodeSpecModel( private fun createVssNodeSpecs( className: String, packageName: String, - specification: VssNodeSpecModel = this, + specModel: VssNodeSpecModel = this, ): List { val propertySpecs = mutableListOf() val members = VssNode::class.declaredMemberProperties @@ -221,7 +221,7 @@ internal class VssNodeSpecModel( fun createInterfaceDataTypeSpec(member: KProperty1): PropertySpec { val memberName = member.name val memberType = member.returnType.asTypeName() - val initialValue = member.get(specification) ?: "" + val initialValue = member.get(specModel) ?: "" return PropertySpec .builder(memberName, memberType) @@ -235,11 +235,11 @@ internal class VssNodeSpecModel( } fun createObjectTypeSpec( - specification: VssNodeSpecModel, + nodeSpecModel: VssNodeSpecModel, packageName: String, ): PropertySpec { - val prefixedTypeName = ClassName(packageName, specification.className) - val variableName = specification.variableName + val prefixedTypeName = ClassName(packageName, nodeSpecModel.className) + val variableName = nodeSpecModel.variableName return PropertySpec .builder(variableName, prefixedTypeName) @@ -248,7 +248,7 @@ internal class VssNodeSpecModel( } // Add primitive data types - if (specification.className == className) { + if (specModel.className == className) { members.forEach { member -> when (member.returnType.asTypeName()) { stringTypeName -> createInterfaceDataTypeSpec(member) @@ -262,13 +262,13 @@ internal class VssNodeSpecModel( } // Add nested child classes - val objectTypeSpec = createObjectTypeSpec(specification, packageName) + val objectTypeSpec = createObjectTypeSpec(specModel, packageName) return listOf(objectTypeSpec) } - private fun createVssNodeTreeSpecs(childSpecifications: List): List { + private fun createVssNodeTreeSpecs(childNodes: List): List { fun createSetSpec(memberName: String, memberType: TypeName): PropertySpec { - val specificationNamesJoined = childSpecifications.joinToString(", ") { it.variableName } + val vssNodeNamesJoined = childNodes.joinToString(", ") { it.variableName } return PropertySpec .builder(memberName, memberType) @@ -276,7 +276,7 @@ internal class VssNodeSpecModel( .addModifiers(KModifier.OVERRIDE) .getter( FunSpec.getterBuilder() - .addStatement("return setOf(%L)", specificationNamesJoined) + .addStatement("return setOf(%L)", vssNodeNamesJoined) .build(), ) .build() diff --git a/vss-processor/src/test/kotlin/org/eclipse/kuksa/vssprocessor/spec/VssNodeSpecModelTest.kt b/vss-processor/src/test/kotlin/org/eclipse/kuksa/vssprocessor/spec/VssNodeSpecModelTest.kt index b296003d..a8c0751d 100644 --- a/vss-processor/src/test/kotlin/org/eclipse/kuksa/vssprocessor/spec/VssNodeSpecModelTest.kt +++ b/vss-processor/src/test/kotlin/org/eclipse/kuksa/vssprocessor/spec/VssNodeSpecModelTest.kt @@ -149,9 +149,9 @@ class VssNodeSpecModelTest : BehaviorSpec({ exception shouldNotBe null } } - and("related specifications") { + and("related nodes") { val vehicleSpeedSpecModel = VssNodeSpecModel(datatype = "float", vssPath = "Vehicle.Speed") - val relatedSpecifications = listOf( + val relatedVssNodes = listOf( VssNodeSpecModel(vssPath = "Vehicle.SmartphoneProjection"), VssNodeSpecModel(datatype = "boolean", vssPath = "Vehicle.IsBrokenDown"), vehicleSpeedSpecModel, @@ -161,7 +161,7 @@ class VssNodeSpecModelTest : BehaviorSpec({ ) `when`("creating a class spec with children") { - val rootClassSpec = specModel.createClassSpec("test", relatedSpecifications) + val rootClassSpec = specModel.createClassSpec("test", relatedVssNodes) then("it should contain the child properties") { val isBrokenDownPropertySpec = rootClassSpec.propertySpecs.find { it.name == "isBrokenDown" } @@ -190,14 +190,14 @@ class VssNodeSpecModelTest : BehaviorSpec({ } } } - and("nested specifications") { - val nestedSpecifications = listOf("Speed") + and("nested nodes") { + val nestedVssNodes = listOf("Speed") `when`("creating a child class spec with nested children") { val classSpec = specModel.createClassSpec( "test", - relatedSpecifications, - nestedSpecifications, + relatedVssNodes, + nestedVssNodes, ) then("it should contain the nested children") { From c0a06a2287318cc2e55d1cd8814d55d7139a7719 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mark=20Hu=CC=88sers?= Date: Thu, 7 Mar 2024 18:22:24 +0100 Subject: [PATCH 16/20] test: Adapt tests to vararg change --- .../databroker/DataBrokerTransporterTest.kt | 12 ++++++------ .../extensions/DataBrokerTransporterExtensions.kt | 10 +++++----- 2 files changed, 11 insertions(+), 11 deletions(-) diff --git a/kuksa-sdk/src/test/kotlin/org/eclipse/kuksa/connectivity/databroker/DataBrokerTransporterTest.kt b/kuksa-sdk/src/test/kotlin/org/eclipse/kuksa/connectivity/databroker/DataBrokerTransporterTest.kt index 3088aaa9..21b6cdeb 100644 --- a/kuksa-sdk/src/test/kotlin/org/eclipse/kuksa/connectivity/databroker/DataBrokerTransporterTest.kt +++ b/kuksa-sdk/src/test/kotlin/org/eclipse/kuksa/connectivity/databroker/DataBrokerTransporterTest.kt @@ -47,14 +47,14 @@ class DataBrokerTransporterTest : BehaviorSpec({ and("Some VSS-related data") { val vssPath = "Vehicle.ADAS.CruiseControl.SpeedSet" - val field = Types.Field.FIELD_VALUE + val fields = setOf(Types.Field.FIELD_VALUE) val random = Random(System.currentTimeMillis()) val valueToSet = random.nextInt(250).toFloat() - `when`("Updating the $field of $vssPath to $valueToSet km/h") { + `when`("Updating the $fields of $vssPath to $valueToSet km/h") { val updatedDatapoint = Types.Datapoint.newBuilder().setFloat(valueToSet).build() val result = kotlin.runCatching { - classUnderTest.update(vssPath, updatedDatapoint, field) + classUnderTest.update(vssPath, updatedDatapoint, fields) } then("No Exception should be thrown") { @@ -69,7 +69,7 @@ class DataBrokerTransporterTest : BehaviorSpec({ } `when`("Fetching the Value of Vehicle.ADAS.CruiseControl.SpeedSet") { - val property = classUnderTest.fetch(vssPath, field) + val property = classUnderTest.fetch(vssPath, fields) then("It should return the correct value") { val dataEntry = property.getEntries(0) @@ -78,11 +78,11 @@ class DataBrokerTransporterTest : BehaviorSpec({ } } - `when`("Trying to fetch the $field from an invalid VSS Path") { + `when`("Trying to fetch the $fields from an invalid VSS Path") { val invalidVssPath = "Vehicle.This.Path.Is.Invalid" val result = kotlin.runCatching { - classUnderTest.fetch(invalidVssPath, field) + classUnderTest.fetch(invalidVssPath, fields) } then("No Exception should be thrown") { diff --git a/kuksa-sdk/src/test/kotlin/org/eclipse/kuksa/extensions/DataBrokerTransporterExtensions.kt b/kuksa-sdk/src/test/kotlin/org/eclipse/kuksa/extensions/DataBrokerTransporterExtensions.kt index b046bd44..4f85f2f1 100644 --- a/kuksa-sdk/src/test/kotlin/org/eclipse/kuksa/extensions/DataBrokerTransporterExtensions.kt +++ b/kuksa-sdk/src/test/kotlin/org/eclipse/kuksa/extensions/DataBrokerTransporterExtensions.kt @@ -34,7 +34,7 @@ internal suspend fun DataBrokerTransporter.updateRandomFloatValue( val updatedDatapoint = Types.Datapoint.newBuilder().setFloat(randomFloat).build() try { - update(vssPath, updatedDatapoint, Types.Field.FIELD_VALUE) + update(vssPath, updatedDatapoint, setOf(Types.Field.FIELD_VALUE)) } catch (e: Exception) { fail("Updating $vssPath to $randomFloat failed: $e") } @@ -51,7 +51,7 @@ internal suspend fun DataBrokerTransporter.updateRandomUint32Value( val updatedDatapoint = Types.Datapoint.newBuilder().setUint32(randomValue).build() try { - update(vssPath, updatedDatapoint, Types.Field.FIELD_VALUE) + update(vssPath, updatedDatapoint, setOf(Types.Field.FIELD_VALUE)) } catch (e: Exception) { fail("Updating $vssPath to $randomValue failed: $e") } @@ -60,17 +60,17 @@ internal suspend fun DataBrokerTransporter.updateRandomUint32Value( } internal suspend fun DataBrokerTransporter.toggleBoolean(vssPath: String): Boolean { - val field = Types.Field.FIELD_VALUE + val fields = setOf(Types.Field.FIELD_VALUE) var newBoolean: Boolean? = null try { - val response = fetch(vssPath, field) + val response = fetch(vssPath, fields) val currentBool = response.entriesList[0].value.bool newBoolean = !currentBool val newDatapoint = Types.Datapoint.newBuilder().setBool(newBoolean).build() - update(vssPath, newDatapoint, field) + update(vssPath, newDatapoint, fields) } catch (e: Exception) { fail("Updating $vssPath to $newBoolean failed: $e") } From b897e0fe71e8cb3b6b8534b5b7d395b5772efd6c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mark=20Hu=CC=88sers?= Date: Fri, 8 Mar 2024 10:48:36 +0100 Subject: [PATCH 17/20] chore: Adapt QUICKSTART to vararg API --- docs/QUICKSTART.md | 14 +++++++------- .../databroker/subscription/VssNodePathListener.kt | 2 +- 2 files changed, 8 insertions(+), 8 deletions(-) diff --git a/docs/QUICKSTART.md b/docs/QUICKSTART.md index f3fb4a68..d4ef8bce 100644 --- a/docs/QUICKSTART.md +++ b/docs/QUICKSTART.md @@ -68,7 +68,7 @@ void connectInsecure(String host, int port) { ```kotlin fun fetch() { lifecycleScope.launch { - val request = FetchRequest("Vehicle.Speed", setOf(Field.FIELD_VALUE)) + val request = FetchRequest("Vehicle.Speed", Field.FIELD_VALUE) val response = dataBrokerConnection?.fetch(request) ?: return@launch val entry = response.entriesList.first() // Don't forget to handle empty responses val value = entry.value @@ -78,14 +78,14 @@ fun fetch() { fun update() { lifecycleScope.launch { - val request = UpdateRequest("Vehicle.Speed", setOf(Field.FIELD_VALUE)) + val request = UpdateRequest("Vehicle.Speed", Field.FIELD_VALUE) val datapoint = Datapoint.newBuilder().setFloat(100f).build() dataBrokerConnection?.update(request, datapoint) } } fun subscribe() { - val request = SubscribeRequest("Vehicle.Speed", setOf(Field.FIELD_VALUE)) + val request = SubscribeRequest("Vehicle.Speed", Field.FIELD_VALUE) val listener = object : VssPathListener { override fun onEntryChanged(entryUpdates: List) { entryUpdates.forEach { entryUpdate -> @@ -106,7 +106,7 @@ fun subscribe() { *Java* ```java void fetch() { - FetchRequest request = new FetchRequest("Vehicle.Speed", Collections.singleton(Types.Field.FIELD_VALUE)); + FetchRequest request = new FetchRequest("Vehicle.Speed", Types.Field.FIELD_VALUE); dataBrokerConnection.fetch(request, new CoroutineCallback() { @Override public void onSuccess(GetResponse result) { @@ -120,7 +120,7 @@ void fetch() { void update() { Datapoint datapoint = Datapoint.newBuilder().setFloat(100f).build(); - UpdateRequest request = new UpdateRequest("Vehicle.Speed", datapoint, Collections.singleton(Types.Field.FIELD_VALUE)); + UpdateRequest request = new UpdateRequest("Vehicle.Speed", datapoint, Types.Field.FIELD_VALUE); dataBrokerConnection.update(request, new CoroutineCallback() { @Override public void onSuccess(KuksaValV1.SetResponse result) { @@ -130,7 +130,7 @@ void update() { } void subscribe() { - SubscribeRequest request = new SubscribeRequest("Vehicle.Speed", Collections.singleton(Types.Field.FIELD_VALUE)); + SubscribeRequest request = new SubscribeRequest("Vehicle.Speed", Types.Field.FIELD_VALUE); dataBrokerConnection.subscribe(request, new VssPathListener() { @Override public void onEntryChanged(@NonNull List entryUpdates) { @@ -181,7 +181,7 @@ vssProcessor { } ``` -Use the [`VssModelGenerator`](https://github.com/eclipse-kuksa/kuksa-android-sdk/blob/main/vss-core/src/main/java/org/eclipse/kuksa/vsscore/annotation/VssModelGenerator.kt) annotation and provide the path to the VSS file (Inside the assets folder). +Use the [`VssModelGenerator`](https://github.com/eclipse-kuksa/kuksa-android-sdk/blob/main/vss-core/src/main/java/org/eclipse/kuksa/vsscore/annotation/VssModelGenerator.kt) annotation. Doing so will generate a complete tree of Kotlin models which can be used in combination with the SDK API. This way you can work with safe types and the SDK takes care of all the model parsing for you. There is also a whole set of convenience operators and extension methods to work with to manipulate the tree data. See the `VssNode` class documentation for this. diff --git a/kuksa-sdk/src/main/kotlin/org/eclipse/kuksa/connectivity/databroker/subscription/VssNodePathListener.kt b/kuksa-sdk/src/main/kotlin/org/eclipse/kuksa/connectivity/databroker/subscription/VssNodePathListener.kt index afe9ac71..4c078a4a 100644 --- a/kuksa-sdk/src/main/kotlin/org/eclipse/kuksa/connectivity/databroker/subscription/VssNodePathListener.kt +++ b/kuksa-sdk/src/main/kotlin/org/eclipse/kuksa/connectivity/databroker/subscription/VssNodePathListener.kt @@ -45,7 +45,7 @@ internal class VssNodePathListener( listener.onError(throwable) } - // Two VssNodeObserverWrapper instances are equal if they have the same observer set! + // Two VssNodePathListener instances are equal if they have the same observer set! override fun equals(other: Any?): Boolean { if (this === other) return true if (javaClass != other?.javaClass) return false From 505b13ac81a43f8de3c6e8f821cf047748ea7c65 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mark=20Hu=CC=88sers?= Date: Fri, 8 Mar 2024 12:55:00 +0100 Subject: [PATCH 18/20] chore: Introduce VssSignal + VssBranch To stick more to the VSS terminology the VssLeaf was renamed to VssSignal. In addition a VssBranch interface was introduced to clearly separate them from VssSignals. --- docs/kuksa-vss-core_class-diagram.puml | 7 ++- .../databroker/DataBrokerConnection.kt | 20 ++++----- .../subscription/DataBrokerSubscriber.kt | 8 ++-- .../kuksa/extension/DataPointExtension.kt | 8 ++-- .../extension/vss/VssLeafBooleanExtension.kt | 4 +- .../extension/vss/VssLeafDoubleExtension.kt | 34 +++++++------- .../extension/vss/VssLeafFloatExtension.kt | 34 +++++++------- .../extension/vss/VssLeafIntExtension.kt | 34 +++++++------- .../extension/vss/VssLeafLongExtension.kt | 34 +++++++------- .../extension/vss/VssNodeCopyExtension.kt | 18 ++++---- .../org/eclipse/kuksa/vssNode/VssDriver.kt | 18 ++++---- .../eclipse/kuksa/vssNode/VssNodeCopyTest.kt | 6 +-- .../org/eclipse/kuksa/vssNode/VssVehicle.kt | 14 +++--- .../eclipse/kuksa/vsscore/model/VssNode.kt | 44 ++++++++++++------- .../kuksa/vsscore/model/VssNodeTest.kt | 2 +- .../eclipse/kuksa/vsscore/model/VssVehicle.kt | 4 +- .../vssprocessor/spec/VssNodeSpecModel.kt | 11 ++--- 17 files changed, 159 insertions(+), 141 deletions(-) diff --git a/docs/kuksa-vss-core_class-diagram.puml b/docs/kuksa-vss-core_class-diagram.puml index b6856aee..52d0a5cd 100644 --- a/docs/kuksa-vss-core_class-diagram.puml +++ b/docs/kuksa-vss-core_class-diagram.puml @@ -3,7 +3,8 @@ !startsub VssCore package VssCore { - VssNode <|- VssLeaf + VssNode <|- VssBranch + VssNode <|-- VssSignal annotation VssModelGenerator @@ -17,7 +18,9 @@ package VssCore { + comment: String } - interface VssLeaf { + interface VssBranch + + interface VssSignal { + value: T } } diff --git a/kuksa-sdk/src/main/kotlin/org/eclipse/kuksa/connectivity/databroker/DataBrokerConnection.kt b/kuksa-sdk/src/main/kotlin/org/eclipse/kuksa/connectivity/databroker/DataBrokerConnection.kt index a0fe92f7..3134f3ee 100644 --- a/kuksa-sdk/src/main/kotlin/org/eclipse/kuksa/connectivity/databroker/DataBrokerConnection.kt +++ b/kuksa-sdk/src/main/kotlin/org/eclipse/kuksa/connectivity/databroker/DataBrokerConnection.kt @@ -43,10 +43,10 @@ import org.eclipse.kuksa.proto.v1.KuksaValV1.GetResponse import org.eclipse.kuksa.proto.v1.KuksaValV1.SetResponse import org.eclipse.kuksa.proto.v1.Types import org.eclipse.kuksa.proto.v1.Types.Datapoint -import org.eclipse.kuksa.vsscore.model.VssLeaf import org.eclipse.kuksa.vsscore.model.VssNode +import org.eclipse.kuksa.vsscore.model.VssSignal import org.eclipse.kuksa.vsscore.model.heritage -import org.eclipse.kuksa.vsscore.model.vssLeafs +import org.eclipse.kuksa.vsscore.model.vssSignals import kotlin.properties.Delegates /** @@ -118,10 +118,10 @@ class DataBrokerConnection internal constructor( } /** - * Subscribes to the specified [VssNode] with the provided [VssNodeListener]. Only a [VssLeaf] + * Subscribes to the specified [VssNode] with the provided [VssNodeListener]. Only a [VssSignal] * can be subscribed because they have an actual value. When provided with any parent [VssNode] then this - * [subscribe] method will find all [VssLeaf] children and subscribes them instead. Once subscribed the - * application will be notified about any changes to every subscribed [VssLeaf]. + * [subscribe] method will find all [VssSignal] children and subscribes them instead. Once subscribed the + * application will be notified about any changes to every subscribed [VssSignal]. * The [VssNodeSubscribeRequest.fields] can be used to subscribe to different information of the [VssNode]. * The default for the [Types.Field] parameter is a list with a single [Types.Field.FIELD_VALUE] entry. * @@ -214,22 +214,22 @@ class DataBrokerConnection internal constructor( } /** - * Only a [VssLeaf] can be updated because they have an actual value. When provided with any parent - * [VssNode] then this [update] method will find all [VssLeaf] children and updates their corresponding + * Only a [VssSignal] can be updated because they have an actual value. When provided with any parent + * [VssNode] then this [update] method will find all [VssSignal] children and updates their corresponding * [Types.Field] instead. * Compared to [update] with only one [UpdateRequest], here multiple [SetResponse] will be returned * because a [VssNode] may consists of multiple values which may need to be updated. * * @throws DataBrokerException in case the connection to the DataBroker is no longer active - * @throws IllegalArgumentException if the [VssLeaf] could not be converted to a [Datapoint]. + * @throws IllegalArgumentException if the [VssSignal] could not be converted to a [Datapoint]. */ @Suppress("performance:SpreadOperator") // Neglectable: Field types are 1-2 elements mostly suspend fun update(request: VssNodeUpdateRequest): Collection { val responses = mutableListOf() val vssNode = request.vssNode - vssNode.vssLeafs.forEach { vssLeaf -> - val simpleUpdateRequest = UpdateRequest(vssLeaf.vssPath, vssLeaf.datapoint, *request.fields) + vssNode.vssSignals.forEach { signal -> + val simpleUpdateRequest = UpdateRequest(signal.vssPath, signal.datapoint, *request.fields) val response = update(simpleUpdateRequest) responses.add(response) diff --git a/kuksa-sdk/src/main/kotlin/org/eclipse/kuksa/connectivity/databroker/subscription/DataBrokerSubscriber.kt b/kuksa-sdk/src/main/kotlin/org/eclipse/kuksa/connectivity/databroker/subscription/DataBrokerSubscriber.kt index 64af55ab..6cd42e4c 100644 --- a/kuksa-sdk/src/main/kotlin/org/eclipse/kuksa/connectivity/databroker/subscription/DataBrokerSubscriber.kt +++ b/kuksa-sdk/src/main/kotlin/org/eclipse/kuksa/connectivity/databroker/subscription/DataBrokerSubscriber.kt @@ -26,8 +26,8 @@ import org.eclipse.kuksa.connectivity.databroker.listener.VssPathListener import org.eclipse.kuksa.extension.TAG import org.eclipse.kuksa.proto.v1.Types import org.eclipse.kuksa.proto.v1.Types.Field -import org.eclipse.kuksa.vsscore.model.VssLeaf import org.eclipse.kuksa.vsscore.model.VssNode +import org.eclipse.kuksa.vsscore.model.VssSignal /** * Creates [DataBrokerSubscription]s to the DataBroker to get notified about changes on the underlying vssPaths and @@ -76,10 +76,10 @@ internal class DataBrokerSubscriber(private val dataBrokerTransporter: DataBroke } /** - * Subscribes to the specified [VssNode] with the provided [VssNodeListener]. Only a [VssLeaf] + * Subscribes to the specified [VssNode] with the provided [VssNodeListener]. Only a [VssSignal] * can be subscribed because they have an actual value. When provided with any parent [VssNode] then this - * [subscribe] method will find all [VssLeaf] children and subscribes them instead. Once subscribed the - * application will be notified about any changes to every subscribed [VssLeaf]. The [field] can be used to + * [subscribe] method will find all [VssSignal] children and subscribes them instead. Once subscribed the + * application will be notified about any changes to every subscribed [VssSignal]. The [field] can be used to * subscribe to different information of the [node]. The default for the [field] parameter is a single * [Types.Field.FIELD_VALUE] entry. * diff --git a/kuksa-sdk/src/main/kotlin/org/eclipse/kuksa/extension/DataPointExtension.kt b/kuksa-sdk/src/main/kotlin/org/eclipse/kuksa/extension/DataPointExtension.kt index 3ecd3e8a..8254d28d 100644 --- a/kuksa-sdk/src/main/kotlin/org/eclipse/kuksa/extension/DataPointExtension.kt +++ b/kuksa-sdk/src/main/kotlin/org/eclipse/kuksa/extension/DataPointExtension.kt @@ -24,7 +24,7 @@ import org.eclipse.kuksa.proto.v1.Types import org.eclipse.kuksa.proto.v1.Types.BoolArray import org.eclipse.kuksa.proto.v1.Types.Datapoint import org.eclipse.kuksa.proto.v1.Types.Datapoint.ValueCase -import org.eclipse.kuksa.vsscore.model.VssLeaf +import org.eclipse.kuksa.vsscore.model.VssSignal private const val CSV_DELIMITER = "," @@ -35,11 +35,11 @@ val Types.Metadata.valueType: ValueCase get() = dataType.dataPointValueCase /** - * Converts the [VssLeaf.value] into a [Datapoint] object. + * Converts the [VssSignal.value] into a [Datapoint] object. * - * @throws IllegalArgumentException if the [VssLeaf] could not be converted to a [Datapoint]. + * @throws IllegalArgumentException if the [VssSignal] could not be converted to a [Datapoint]. */ -val VssLeaf.datapoint: Datapoint +val VssSignal.datapoint: Datapoint get() { val stringValue = value.toString() return when (value::class) { diff --git a/kuksa-sdk/src/main/kotlin/org/eclipse/kuksa/extension/vss/VssLeafBooleanExtension.kt b/kuksa-sdk/src/main/kotlin/org/eclipse/kuksa/extension/vss/VssLeafBooleanExtension.kt index 7b75eeba..c62c1df9 100644 --- a/kuksa-sdk/src/main/kotlin/org/eclipse/kuksa/extension/vss/VssLeafBooleanExtension.kt +++ b/kuksa-sdk/src/main/kotlin/org/eclipse/kuksa/extension/vss/VssLeafBooleanExtension.kt @@ -18,7 +18,7 @@ package org.eclipse.kuksa.extension.vss -import org.eclipse.kuksa.vsscore.model.VssLeaf +import org.eclipse.kuksa.vsscore.model.VssSignal /** * Convenience operator for [copy] with a [Boolean] value which will be inverted. @@ -26,6 +26,6 @@ import org.eclipse.kuksa.vsscore.model.VssLeaf * @throws [IllegalArgumentException] if the copied types do not match. * @throws [NoSuchElementException] if no copy method was found for the class. */ -operator fun VssLeaf.not(): VssLeaf { +operator fun VssSignal.not(): VssSignal { return copy(!value) } diff --git a/kuksa-sdk/src/main/kotlin/org/eclipse/kuksa/extension/vss/VssLeafDoubleExtension.kt b/kuksa-sdk/src/main/kotlin/org/eclipse/kuksa/extension/vss/VssLeafDoubleExtension.kt index ed3a405b..08e55bae 100644 --- a/kuksa-sdk/src/main/kotlin/org/eclipse/kuksa/extension/vss/VssLeafDoubleExtension.kt +++ b/kuksa-sdk/src/main/kotlin/org/eclipse/kuksa/extension/vss/VssLeafDoubleExtension.kt @@ -18,86 +18,86 @@ package org.eclipse.kuksa.extension.vss -import org.eclipse.kuksa.vsscore.model.VssLeaf +import org.eclipse.kuksa.vsscore.model.VssSignal /** - * Convenience operator for [copy] which updates the [VssLeaf.value] by adding [value] to it. + * Convenience operator for [copy] which updates the [VssSignal.value] by adding [value] to it. * * @throws [IllegalArgumentException] if the copied types do not match. * @throws [NoSuchElementException] if no copy method was found for the class. */ -operator fun VssLeaf.plusAssign(value: Number) { +operator fun VssSignal.plusAssign(value: Number) { copy(this.value + value.toDouble()) } /** - * Convenience operator for [copy] which updates the [VssLeaf.value] by adding [value] to it. + * Convenience operator for [copy] which updates the [VssSignal.value] by adding [value] to it. * * @throws [IllegalArgumentException] if the copied types do not match. * @throws [NoSuchElementException] if no copy method was found for the class. */ -operator fun VssLeaf.plus(value: Number): VssLeaf { +operator fun VssSignal.plus(value: Number): VssSignal { return copy(this.value + value.toDouble()) } /** - * Convenience operator for [copy] which updates the [VssLeaf.value] by subtracting [value] to it. + * Convenience operator for [copy] which updates the [VssSignal.value] by subtracting [value] to it. * * @throws [IllegalArgumentException] if the copied types do not match. * @throws [NoSuchElementException] if no copy method was found for the class. */ -operator fun VssLeaf.minusAssign(value: Number) { +operator fun VssSignal.minusAssign(value: Number) { copy(this.value - value.toDouble()) } /** - * Convenience operator for [copy] which updates the [VssLeaf.value] by subtracting [value] to it. + * Convenience operator for [copy] which updates the [VssSignal.value] by subtracting [value] to it. * * @throws [IllegalArgumentException] if the copied types do not match. * @throws [NoSuchElementException] if no copy method was found for the class. */ -operator fun VssLeaf.minus(value: Number): VssLeaf { +operator fun VssSignal.minus(value: Number): VssSignal { return copy(this.value - value.toDouble()) } /** - * Convenience operator for [copy] which updates the [VssLeaf.value] by dividing [value] to it. + * Convenience operator for [copy] which updates the [VssSignal.value] by dividing [value] to it. * * @throws [IllegalArgumentException] if the copied types do not match. * @throws [NoSuchElementException] if no copy method was found for the class. * @throws [ArithmeticException] if divided by zero. */ -operator fun VssLeaf.divAssign(value: Number) { +operator fun VssSignal.divAssign(value: Number) { copy(this.value / value.toDouble()) } /** - * Convenience operator for [copy] which updates the [VssLeaf.value] by dividing [value] to it. + * Convenience operator for [copy] which updates the [VssSignal.value] by dividing [value] to it. * * @throws [IllegalArgumentException] if the copied types do not match. * @throws [NoSuchElementException] if no copy method was found for the class. * @throws [ArithmeticException] if divided by zero. */ -operator fun VssLeaf.div(value: Number): VssLeaf { +operator fun VssSignal.div(value: Number): VssSignal { return copy(this.value / value.toDouble()) } /** - * Convenience operator for [copy] which updates the [VssLeaf.value] by multiplying [value] to it. + * Convenience operator for [copy] which updates the [VssSignal.value] by multiplying [value] to it. * * @throws [IllegalArgumentException] if the copied types do not match. * @throws [NoSuchElementException] if no copy method was found for the class. */ -operator fun VssLeaf.timesAssign(value: Number) { +operator fun VssSignal.timesAssign(value: Number) { copy(this.value * value.toDouble()) } /** - * Convenience operator for [copy] which updates the [VssLeaf.value] by multiplying [value] to it. + * Convenience operator for [copy] which updates the [VssSignal.value] by multiplying [value] to it. * * @throws [IllegalArgumentException] if the copied types do not match. * @throws [NoSuchElementException] if no copy method was found for the class. */ -operator fun VssLeaf.times(value: Number): VssLeaf { +operator fun VssSignal.times(value: Number): VssSignal { return copy(this.value * value.toDouble()) } diff --git a/kuksa-sdk/src/main/kotlin/org/eclipse/kuksa/extension/vss/VssLeafFloatExtension.kt b/kuksa-sdk/src/main/kotlin/org/eclipse/kuksa/extension/vss/VssLeafFloatExtension.kt index 083bdc2e..68463dc9 100644 --- a/kuksa-sdk/src/main/kotlin/org/eclipse/kuksa/extension/vss/VssLeafFloatExtension.kt +++ b/kuksa-sdk/src/main/kotlin/org/eclipse/kuksa/extension/vss/VssLeafFloatExtension.kt @@ -18,86 +18,86 @@ package org.eclipse.kuksa.extension.vss -import org.eclipse.kuksa.vsscore.model.VssLeaf +import org.eclipse.kuksa.vsscore.model.VssSignal /** - * Convenience operator for [copy] which updates the [VssLeaf.value] by adding [value] to it. + * Convenience operator for [copy] which updates the [VssSignal.value] by adding [value] to it. * * @throws [IllegalArgumentException] if the copied types do not match. * @throws [NoSuchElementException] if no copy method was found for the class. */ -operator fun VssLeaf.plusAssign(value: Number) { +operator fun VssSignal.plusAssign(value: Number) { copy(this.value + value.toFloat()) } /** - * Convenience operator for [copy] which updates the [VssLeaf.value] by adding [value] to it. + * Convenience operator for [copy] which updates the [VssSignal.value] by adding [value] to it. * * @throws [IllegalArgumentException] if the copied types do not match. * @throws [NoSuchElementException] if no copy method was found for the class. */ -operator fun VssLeaf.plus(value: Number): VssLeaf { +operator fun VssSignal.plus(value: Number): VssSignal { return copy(this.value + value.toFloat()) } /** - * Convenience operator for [copy] which updates the [VssLeaf.value] by subtracting [value] to it. + * Convenience operator for [copy] which updates the [VssSignal.value] by subtracting [value] to it. * * @throws [IllegalArgumentException] if the copied types do not match. * @throws [NoSuchElementException] if no copy method was found for the class. */ -operator fun VssLeaf.minusAssign(value: Number) { +operator fun VssSignal.minusAssign(value: Number) { copy(this.value - +value.toFloat()) } /** - * Convenience operator for [copy] which updates the [VssLeaf.value] by subtracting [value] to it. + * Convenience operator for [copy] which updates the [VssSignal.value] by subtracting [value] to it. * * @throws [IllegalArgumentException] if the copied types do not match. * @throws [NoSuchElementException] if no copy method was found for the class. */ -operator fun VssLeaf.minus(value: Number): VssLeaf { +operator fun VssSignal.minus(value: Number): VssSignal { return copy(this.value - +value.toFloat()) } /** - * Convenience operator for [copy] which updates the [VssLeaf.value] by dividing [value] to it. + * Convenience operator for [copy] which updates the [VssSignal.value] by dividing [value] to it. * * @throws [IllegalArgumentException] if the copied types do not match. * @throws [NoSuchElementException] if no copy method was found for the class. * @throws [ArithmeticException] if divided by zero. */ -operator fun VssLeaf.divAssign(value: Number) { +operator fun VssSignal.divAssign(value: Number) { copy(this.value / +value.toFloat()) } /** - * Convenience operator for [copy] which updates the [VssLeaf.value] by dividing [value] to it. + * Convenience operator for [copy] which updates the [VssSignal.value] by dividing [value] to it. * * @throws [IllegalArgumentException] if the copied types do not match. * @throws [NoSuchElementException] if no copy method was found for the class. * @throws [ArithmeticException] if divided by zero. */ -operator fun VssLeaf.div(value: Number): VssLeaf { +operator fun VssSignal.div(value: Number): VssSignal { return copy(this.value / +value.toFloat()) } /** - * Convenience operator for [copy] which updates the [VssLeaf.value] by dividing [value] to it. + * Convenience operator for [copy] which updates the [VssSignal.value] by dividing [value] to it. * * @throws [IllegalArgumentException] if the copied types do not match. * @throws [NoSuchElementException] if no copy method was found for the class. */ -operator fun VssLeaf.timesAssign(value: Number) { +operator fun VssSignal.timesAssign(value: Number) { copy(this.value * +value.toFloat()) } /** - * Convenience operator for [copy] which updates the [VssLeaf.value] by dividing [value] to it. + * Convenience operator for [copy] which updates the [VssSignal.value] by dividing [value] to it. * * @throws [IllegalArgumentException] if the copied types do not match. * @throws [NoSuchElementException] if no copy method was found for the class. */ -operator fun VssLeaf.times(value: Number): VssLeaf { +operator fun VssSignal.times(value: Number): VssSignal { return copy(this.value * +value.toFloat()) } diff --git a/kuksa-sdk/src/main/kotlin/org/eclipse/kuksa/extension/vss/VssLeafIntExtension.kt b/kuksa-sdk/src/main/kotlin/org/eclipse/kuksa/extension/vss/VssLeafIntExtension.kt index b0e74aeb..bd0464fd 100644 --- a/kuksa-sdk/src/main/kotlin/org/eclipse/kuksa/extension/vss/VssLeafIntExtension.kt +++ b/kuksa-sdk/src/main/kotlin/org/eclipse/kuksa/extension/vss/VssLeafIntExtension.kt @@ -18,86 +18,86 @@ package org.eclipse.kuksa.extension.vss -import org.eclipse.kuksa.vsscore.model.VssLeaf +import org.eclipse.kuksa.vsscore.model.VssSignal /** - * Convenience operator for [copy] which updates the [VssLeaf.value] by adding [value] to it. + * Convenience operator for [copy] which updates the [VssSignal.value] by adding [value] to it. * * @throws [IllegalArgumentException] if the copied types do not match. * @throws [NoSuchElementException] if no copy method was found for the class. */ -operator fun VssLeaf.plusAssign(value: Number) { +operator fun VssSignal.plusAssign(value: Number) { copy(this.value + value.toInt()) } /** - * Convenience operator for [copy] which updates the [VssLeaf.value] by adding [value] to it. + * Convenience operator for [copy] which updates the [VssSignal.value] by adding [value] to it. * * @throws [IllegalArgumentException] if the copied types do not match. * @throws [NoSuchElementException] if no copy method was found for the class. */ -operator fun VssLeaf.plus(value: Number): VssLeaf { +operator fun VssSignal.plus(value: Number): VssSignal { return copy(this.value + value.toInt()) } /** - * Convenience operator for [copy] which updates the [VssLeaf.value] by subtracting [value] to it. + * Convenience operator for [copy] which updates the [VssSignal.value] by subtracting [value] to it. * * @throws [IllegalArgumentException] if the copied types do not match. * @throws [NoSuchElementException] if no copy method was found for the class. */ -operator fun VssLeaf.minusAssign(value: Number) { +operator fun VssSignal.minusAssign(value: Number) { copy(this.value - value.toInt()) } /** - * Convenience operator for [copy] which updates the [VssLeaf.value] by subtracting [value] to it. + * Convenience operator for [copy] which updates the [VssSignal.value] by subtracting [value] to it. * * @throws [IllegalArgumentException] if the copied types do not match. * @throws [NoSuchElementException] if no copy method was found for the class. */ -operator fun VssLeaf.minus(value: Number): VssLeaf { +operator fun VssSignal.minus(value: Number): VssSignal { return copy(this.value - value.toInt()) } /** - * Convenience operator for [copy] which updates the [VssLeaf.value] by dividing [value] to it. + * Convenience operator for [copy] which updates the [VssSignal.value] by dividing [value] to it. * * @throws [IllegalArgumentException] if the copied types do not match. * @throws [NoSuchElementException] if no copy method was found for the class. * @throws [ArithmeticException] if divided by zero. */ -operator fun VssLeaf.divAssign(value: Number) { +operator fun VssSignal.divAssign(value: Number) { copy(this.value / value.toInt()) } /** - * Convenience operator for [copy] which updates the [VssLeaf.value] by dividing [value] to it. + * Convenience operator for [copy] which updates the [VssSignal.value] by dividing [value] to it. * * @throws [IllegalArgumentException] if the copied types do not match. * @throws [NoSuchElementException] if no copy method was found for the class. * @throws [ArithmeticException] if divided by zero. */ -operator fun VssLeaf.div(value: Number): VssLeaf { +operator fun VssSignal.div(value: Number): VssSignal { return copy(this.value / value.toInt()) } /** - * Convenience operator for [copy] which updates the [VssLeaf.value] by multiplying [value] to it. + * Convenience operator for [copy] which updates the [VssSignal.value] by multiplying [value] to it. * * @throws [IllegalArgumentException] if the copied types do not match. * @throws [NoSuchElementException] if no copy method was found for the class. */ -operator fun VssLeaf.timesAssign(value: Number) { +operator fun VssSignal.timesAssign(value: Number) { copy(this.value * value.toInt()) } /** - * Convenience operator for [copy] which updates the [VssLeaf.value] by multiplying [value] to it. + * Convenience operator for [copy] which updates the [VssSignal.value] by multiplying [value] to it. * * @throws [IllegalArgumentException] if the copied types do not match. * @throws [NoSuchElementException] if no copy method was found for the class. */ -operator fun VssLeaf.times(value: Number): VssLeaf { +operator fun VssSignal.times(value: Number): VssSignal { return copy(this.value * value.toInt()) } diff --git a/kuksa-sdk/src/main/kotlin/org/eclipse/kuksa/extension/vss/VssLeafLongExtension.kt b/kuksa-sdk/src/main/kotlin/org/eclipse/kuksa/extension/vss/VssLeafLongExtension.kt index 87c53569..0e819187 100644 --- a/kuksa-sdk/src/main/kotlin/org/eclipse/kuksa/extension/vss/VssLeafLongExtension.kt +++ b/kuksa-sdk/src/main/kotlin/org/eclipse/kuksa/extension/vss/VssLeafLongExtension.kt @@ -18,86 +18,86 @@ package org.eclipse.kuksa.extension.vss -import org.eclipse.kuksa.vsscore.model.VssLeaf +import org.eclipse.kuksa.vsscore.model.VssSignal /** - * Convenience operator for [copy] which updates the [VssLeaf.value] by adding [value] to it. + * Convenience operator for [copy] which updates the [VssSignal.value] by adding [value] to it. * * @throws [IllegalArgumentException] if the copied types do not match. * @throws [NoSuchElementException] if no copy method was found for the class. */ -operator fun VssLeaf.plusAssign(value: Number) { +operator fun VssSignal.plusAssign(value: Number) { copy(this.value + value.toLong()) } /** - * Convenience operator for [copy] which updates the [VssLeaf.value] by adding [value] to it. + * Convenience operator for [copy] which updates the [VssSignal.value] by adding [value] to it. * * @throws [IllegalArgumentException] if the copied types do not match. * @throws [NoSuchElementException] if no copy method was found for the class. */ -operator fun VssLeaf.plus(value: Number): VssLeaf { +operator fun VssSignal.plus(value: Number): VssSignal { return copy(this.value + value.toLong()) } /** - * Convenience operator for [copy] which updates the [VssLeaf.value] by subtracting [value] to it. + * Convenience operator for [copy] which updates the [VssSignal.value] by subtracting [value] to it. * * @throws [IllegalArgumentException] if the copied types do not match. * @throws [NoSuchElementException] if no copy method was found for the class. */ -operator fun VssLeaf.minusAssign(value: Number) { +operator fun VssSignal.minusAssign(value: Number) { copy(this.value - value.toLong()) } /** - * Convenience operator for [copy] which updates the [VssLeaf.value] by subtracting [value] to it. + * Convenience operator for [copy] which updates the [VssSignal.value] by subtracting [value] to it. * * @throws [IllegalArgumentException] if the copied types do not match. * @throws [NoSuchElementException] if no copy method was found for the class. */ -operator fun VssLeaf.minus(value: Number): VssLeaf { +operator fun VssSignal.minus(value: Number): VssSignal { return copy(this.value - value.toLong()) } /** - * Convenience operator for [copy] which updates the [VssLeaf.value] by dividing [value] to it. + * Convenience operator for [copy] which updates the [VssSignal.value] by dividing [value] to it. * * @throws [IllegalArgumentException] if the copied types do not match. * @throws [NoSuchElementException] if no copy method was found for the class. * @throws [ArithmeticException] if divided by zero. */ -operator fun VssLeaf.divAssign(value: Number) { +operator fun VssSignal.divAssign(value: Number) { copy(this.value / value.toLong()) } /** - * Convenience operator for [copy] which updates the [VssLeaf.value] by dividing [value] to it. + * Convenience operator for [copy] which updates the [VssSignal.value] by dividing [value] to it. * * @throws [IllegalArgumentException] if the copied types do not match. * @throws [NoSuchElementException] if no copy method was found for the class. * @throws [ArithmeticException] if divided by zero. */ -operator fun VssLeaf.div(value: Number): VssLeaf { +operator fun VssSignal.div(value: Number): VssSignal { return copy(this.value / value.toLong()) } /** - * Convenience operator for [copy] which updates the [VssLeaf.value] by multiplying [value] to it. + * Convenience operator for [copy] which updates the [VssSignal.value] by multiplying [value] to it. * * @throws [IllegalArgumentException] if the copied types do not match. * @throws [NoSuchElementException] if no copy method was found for the class. */ -operator fun VssLeaf.timesAssign(value: Number) { +operator fun VssSignal.timesAssign(value: Number) { copy(this.value * value.toLong()) } /** - * Convenience operator for [copy] which updates the [VssLeaf.value] by multiplying [value] to it. + * Convenience operator for [copy] which updates the [VssSignal.value] by multiplying [value] to it. * * @throws [IllegalArgumentException] if the copied types do not match. * @throws [NoSuchElementException] if no copy method was found for the class. */ -operator fun VssLeaf.times(value: Number): VssLeaf { +operator fun VssSignal.times(value: Number): VssSignal { return copy(this.value * value.toLong()) } diff --git a/kuksa-sdk/src/main/kotlin/org/eclipse/kuksa/extension/vss/VssNodeCopyExtension.kt b/kuksa-sdk/src/main/kotlin/org/eclipse/kuksa/extension/vss/VssNodeCopyExtension.kt index d1cfff51..a128d35e 100644 --- a/kuksa-sdk/src/main/kotlin/org/eclipse/kuksa/extension/vss/VssNodeCopyExtension.kt +++ b/kuksa-sdk/src/main/kotlin/org/eclipse/kuksa/extension/vss/VssNodeCopyExtension.kt @@ -22,8 +22,8 @@ import org.eclipse.kuksa.extension.copy import org.eclipse.kuksa.proto.v1.Types import org.eclipse.kuksa.proto.v1.Types.Datapoint import org.eclipse.kuksa.proto.v1.Types.Datapoint.ValueCase.* -import org.eclipse.kuksa.vsscore.model.VssLeaf import org.eclipse.kuksa.vsscore.model.VssNode +import org.eclipse.kuksa.vsscore.model.VssSignal import org.eclipse.kuksa.vsscore.model.findHeritageLine import org.eclipse.kuksa.vsscore.model.heritage import org.eclipse.kuksa.vsscore.model.variableName @@ -50,7 +50,7 @@ import kotlin.reflect.full.memberProperties // The suggested method to improve the performance can't be used here because we are already working with a full array. // https://detekt.dev/docs/rules/performance/ fun T.deepCopy(generation: Int = 0, changedHeritage: List): T { - if (generation == changedHeritage.size) { // Reached the end, use the changed [VssLeaf] + if (generation == changedHeritage.size) { // Reached the end, use the changed VssSignal return this } @@ -81,11 +81,11 @@ fun T.deepCopy(vararg vssNodes: VssNode): T { } /** - * Creates a copy of a [VssLeaf] where the [VssLeaf.value] is changed to the given [Datapoint]. + * Creates a copy of a [VssSignal] where the [VssSignal.value] is changed to the given [Datapoint]. */ // The actual value type is unknown but it is expected that the casted [valueCase] is valid if no exception was thrown. @Suppress("UNCHECKED_CAST") -fun VssLeaf.copy(datapoint: Datapoint): VssLeaf { +fun VssSignal.copy(datapoint: Datapoint): VssSignal { with(datapoint) { val value: Any = when (valueCase) { STRING -> string @@ -133,13 +133,13 @@ fun VssLeaf.copy(datapoint: Datapoint): VssLeaf { } /** - * Calls the generated copy method of the data class for the [VssLeaf] and returns a new copy with the new [value]. + * Calls the generated copy method of the data class for the [VssSignal] and returns a new copy with the new [value]. * * @throws [IllegalArgumentException] if the copied types do not match. * @throws [NoSuchElementException] if no copy method was found for the class. */ -fun VssLeaf.copy(value: T): VssLeaf { - val memberProperties = VssLeaf::class.memberProperties +fun VssSignal.copy(value: T): VssSignal { + val memberProperties = VssSignal::class.memberProperties val firstPropertyName = memberProperties.first().name val valueMap = mapOf(firstPropertyName to value) @@ -165,7 +165,7 @@ fun T.copy( ): T { val vssNodes = consideredHeritage + this val vssNode = vssNodes - .filterIsInstance>() + .filterIsInstance>() .find { it.vssPath == vssPath } ?: return this val updatedVssNode = vssNode.copy(updatedValue) @@ -195,7 +195,7 @@ operator fun T.invoke(vararg vssNodes: VssNode): T { * @throws [IllegalArgumentException] if the copied types do not match. * @throws [NoSuchElementException] if no copy method was found for the class. */ -operator fun VssLeaf.invoke(value: T): VssLeaf { +operator fun VssSignal.invoke(value: T): VssSignal { return copy(value) } diff --git a/kuksa-sdk/src/test/kotlin/org/eclipse/kuksa/vssNode/VssDriver.kt b/kuksa-sdk/src/test/kotlin/org/eclipse/kuksa/vssNode/VssDriver.kt index 995ab6dd..d81fc36f 100644 --- a/kuksa-sdk/src/test/kotlin/org/eclipse/kuksa/vssNode/VssDriver.kt +++ b/kuksa-sdk/src/test/kotlin/org/eclipse/kuksa/vssNode/VssDriver.kt @@ -19,8 +19,8 @@ package org.eclipse.kuksa.vssNode -import org.eclipse.kuksa.vsscore.model.VssLeaf import org.eclipse.kuksa.vsscore.model.VssNode +import org.eclipse.kuksa.vsscore.model.VssSignal import kotlin.reflect.KClass data class VssDriver @JvmOverloads constructor( @@ -63,7 +63,7 @@ data class VssDriver @JvmOverloads constructor( data class VssHeartRate @JvmOverloads constructor( override val `value`: Int = 0, - ) : VssLeaf { + ) : VssSignal { override val comment: String get() = "" @@ -89,7 +89,7 @@ data class VssDriver @JvmOverloads constructor( data class VssAttentiveProbability @JvmOverloads constructor( override val `value`: Float = 0f, -) : VssLeaf { +) : VssSignal { override val comment: String get() = "" @@ -114,7 +114,7 @@ data class VssAttentiveProbability @JvmOverloads constructor( data class VssDistractionLevel @JvmOverloads constructor( override val `value`: Float = 0f, -) : VssLeaf { +) : VssSignal { override val comment: String get() = "" @@ -139,7 +139,7 @@ data class VssDistractionLevel @JvmOverloads constructor( data class VssFatigueLevel @JvmOverloads constructor( override val `value`: Float = 0f, -) : VssLeaf { +) : VssSignal { override val comment: String get() = "" @@ -190,7 +190,7 @@ data class VssIdentifier @JvmOverloads constructor( data class VssIssuer @JvmOverloads constructor( override val `value`: String = "", -) : VssLeaf { +) : VssSignal { override val comment: String get() = "" @@ -216,7 +216,7 @@ data class VssIssuer @JvmOverloads constructor( data class VssSubject @JvmOverloads constructor( override val `value`: String = "", -) : VssLeaf { +) : VssSignal { override val comment: String get() = "" @@ -241,7 +241,7 @@ data class VssSubject @JvmOverloads constructor( data class VssIsEyesOnRoad @JvmOverloads constructor( override val `value`: Boolean = false, -) : VssLeaf { +) : VssSignal { override val comment: String get() = "" @@ -266,7 +266,7 @@ data class VssIsEyesOnRoad @JvmOverloads constructor( data class VssIsHandsOnWheel @JvmOverloads constructor( override val `value`: Boolean = false, -) : VssLeaf { +) : VssSignal { override val comment: String get() = "" diff --git a/kuksa-sdk/src/test/kotlin/org/eclipse/kuksa/vssNode/VssNodeCopyTest.kt b/kuksa-sdk/src/test/kotlin/org/eclipse/kuksa/vssNode/VssNodeCopyTest.kt index 343156b1..3e711dd6 100644 --- a/kuksa-sdk/src/test/kotlin/org/eclipse/kuksa/vssNode/VssNodeCopyTest.kt +++ b/kuksa-sdk/src/test/kotlin/org/eclipse/kuksa/vssNode/VssNodeCopyTest.kt @@ -30,14 +30,14 @@ import org.eclipse.kuksa.extension.vss.invoke import org.eclipse.kuksa.extension.vss.not import org.eclipse.kuksa.proto.v1.Types import org.eclipse.kuksa.test.kotest.Unit -import org.eclipse.kuksa.vsscore.model.VssLeaf +import org.eclipse.kuksa.vsscore.model.VssSignal class VssNodeCopyTest : BehaviorSpec({ tags(Unit) given("A VssNode") { val vehicle = VssVehicle() - val driverHeartRate: VssLeaf = vehicle.driver.heartRate + val driverHeartRate: VssSignal = vehicle.driver.heartRate and("a changed heritage line") { val newValue = 70 @@ -109,7 +109,7 @@ class VssNodeCopyTest : BehaviorSpec({ and("an empty DataPoint") { val datapoint = Types.Datapoint.newBuilder().build() - and("an invalid VssLeaf") { + and("an invalid VssSignal") { val vssInvalid = VssInvalid() `when`("a copy is done") { diff --git a/kuksa-sdk/src/test/kotlin/org/eclipse/kuksa/vssNode/VssVehicle.kt b/kuksa-sdk/src/test/kotlin/org/eclipse/kuksa/vssNode/VssVehicle.kt index ee8fb11a..ff1cad8a 100644 --- a/kuksa-sdk/src/test/kotlin/org/eclipse/kuksa/vssNode/VssVehicle.kt +++ b/kuksa-sdk/src/test/kotlin/org/eclipse/kuksa/vssNode/VssVehicle.kt @@ -19,8 +19,8 @@ package org.eclipse.kuksa.vssNode -import org.eclipse.kuksa.vsscore.model.VssLeaf import org.eclipse.kuksa.vsscore.model.VssNode +import org.eclipse.kuksa.vsscore.model.VssSignal import kotlin.reflect.KClass data class VssVehicle( @@ -68,7 +68,7 @@ data class VssPassenger( override val type: String = "sensor", override val comment: String = "", override val value: Int = 80, - ) : VssLeaf { + ) : VssSignal { override val parentClass: KClass<*> get() = VssPassenger::class } @@ -81,7 +81,7 @@ data class VssValueInt( override val type: String = "sensor", override val comment: String = "", override val value: Int = 0, -) : VssLeaf +) : VssSignal data class VssValueFloat( override val uuid: String = "Value", @@ -90,7 +90,7 @@ data class VssValueFloat( override val type: String = "sensor", override val comment: String = "", override val value: Float = 0f, -) : VssLeaf +) : VssSignal data class VssValueDouble( override val uuid: String = "Value", @@ -99,7 +99,7 @@ data class VssValueDouble( override val type: String = "sensor", override val comment: String = "", override val value: Double = 0.0, -) : VssLeaf +) : VssSignal data class VssValueLong( override val uuid: String = "Value", @@ -108,7 +108,7 @@ data class VssValueLong( override val type: String = "sensor", override val comment: String = "", override val value: Long = 0L, -) : VssLeaf +) : VssSignal data class VssInvalid( override val uuid: String = "Invalid", @@ -117,4 +117,4 @@ data class VssInvalid( override val type: String = "", override val comment: String = "", override val value: Exception = Exception(), -) : VssLeaf +) : VssSignal diff --git a/vss-core/src/main/kotlin/org/eclipse/kuksa/vsscore/model/VssNode.kt b/vss-core/src/main/kotlin/org/eclipse/kuksa/vsscore/model/VssNode.kt index 6f400198..378e3687 100644 --- a/vss-core/src/main/kotlin/org/eclipse/kuksa/vsscore/model/VssNode.kt +++ b/vss-core/src/main/kotlin/org/eclipse/kuksa/vsscore/model/VssNode.kt @@ -44,7 +44,7 @@ interface VssNode { val description: String /** - * Most relevant for [VssLeaf] nodes. They can be of the type "Sensor" or "Actuator". + * Most relevant for [VssSignal] nodes. They can be of the type "Sensor" or "Actuator". * For Nodes with children this will always be "branch". */ val type: String @@ -57,6 +57,8 @@ interface VssNode { /** * A collection of all initialized children. */ + // Always empty for VssSignals. If this is moved to the VssBranch interface then it introduces some API + // inconveniences because most search API return a VssNode so a cast is always necessary for further searches. val children: Set get() = emptySet() @@ -68,10 +70,19 @@ interface VssNode { } /** - * Some [VssNode] may have an additional [value] property. These are children [VssLeaf] which do not have other + * Defines a [VssNode] which is not a [VssSignal] and only acts as a branch with one or more children. The [type] is + * always "branch". + */ +interface VssBranch : VssNode { + override val type: String + get() = "branch" +} + +/** + * Some [VssNode] may have an additional [value] property. These are children [VssSignal] which do not have other * children. */ -interface VssLeaf : VssNode { +interface VssSignal : VssNode { /** * A primitive type value. */ @@ -131,18 +142,21 @@ val VssNode.parentClassName: String } /** - * Iterates through all nested children which also may have children and aggregates them into one big collection. + * Iterates through all nested children of the [VssNode] which also may have children and aggregates them into one + * big collection. */ val VssNode.heritage: Collection - get() = children.toList() + children.flatMap { it.heritage } + get() = children.toList() + children + .filterIsInstance() + .flatMap { it.heritage } /** - * Finds the latest generation in the form of [VssLeaf] for the current [VssNode]. + * Finds the latest generation in the form of [VssSignal] for the current [VssNode]. */ -val VssNode.vssLeafs: Collection> +val VssNode.vssSignals: Collection> get() = heritage .ifEmpty { setOf(this) } - .filterIsInstance>() + .filterIsInstance>() /** * Uses the [variablePrefix] to generate a unique variable name. The first character is at least lowercased. @@ -209,21 +223,21 @@ fun VssNode.findHeritageLine( } /** - * Finds the given [leaf] inside the current [VssNode]. + * Finds the given [signal] inside the current [VssNode]. */ -fun , V : Any> VssNode.findLeaf(leaf: VssLeaf): VssLeaf { +inline fun , V : Any> VssNode.findSignal(signal: T): T { return heritage - .filterIsInstance>() - .first { it.uuid == leaf.uuid } + .filterIsInstance() + .first { it.uuid == signal.uuid } } /** - * Finds all [VssLeaf] which matches the given [KClass.simpleName]. This is useful when multiple nested objects + * Finds all [VssSignal] which matches the given [KClass.simpleName]. This is useful when multiple nested objects * with the same Name exists but are pretty much the same besides the [VssNode.vssPath] etc. */ -fun , V : Any> VssNode.findLeaf(type: KClass): Map> { +inline fun , V : Any> VssNode.findSignal(type: KClass): Map { return heritage - .filterIsInstance>() + .filterIsInstance() .filter { it::class.simpleName == type.simpleName } .associateBy { it.vssPath } } diff --git a/vss-core/src/test/kotlin/org/eclipse/kuksa/vsscore/model/VssNodeTest.kt b/vss-core/src/test/kotlin/org/eclipse/kuksa/vsscore/model/VssNodeTest.kt index b5986301..51ee4ec2 100644 --- a/vss-core/src/test/kotlin/org/eclipse/kuksa/vsscore/model/VssNodeTest.kt +++ b/vss-core/src/test/kotlin/org/eclipse/kuksa/vsscore/model/VssNodeTest.kt @@ -43,7 +43,7 @@ class VssNodeTest : BehaviorSpec({ } } `when`("finding specific leafs") { - val leafs = vssVehicle.findLeaf(VssDriver.VssHeartRate::class) + val leafs = vssVehicle.findSignal(VssDriver.VssHeartRate::class) then("it should return all leafs which fit the class") { leafs.size shouldBe 2 } diff --git a/vss-core/src/test/kotlin/org/eclipse/kuksa/vsscore/model/VssVehicle.kt b/vss-core/src/test/kotlin/org/eclipse/kuksa/vsscore/model/VssVehicle.kt index 2e3d7f35..eb237186 100644 --- a/vss-core/src/test/kotlin/org/eclipse/kuksa/vsscore/model/VssVehicle.kt +++ b/vss-core/src/test/kotlin/org/eclipse/kuksa/vsscore/model/VssVehicle.kt @@ -66,7 +66,7 @@ data class VssDriver( override val type: String = "sensor", override val comment: String = "", override val value: Int = 100, - ) : VssLeaf { + ) : VssSignal { override val parentClass: KClass<*> get() = VssDriver::class } @@ -92,7 +92,7 @@ data class VssPassenger( override val type: String = "sensor", override val comment: String = "", override val value: Int = 80, - ) : VssLeaf { + ) : VssSignal { override val parentClass: KClass<*> get() = VssPassenger::class } diff --git a/vss-processor/src/main/kotlin/org/eclipse/kuksa/vssprocessor/spec/VssNodeSpecModel.kt b/vss-processor/src/main/kotlin/org/eclipse/kuksa/vssprocessor/spec/VssNodeSpecModel.kt index 32b41792..29eebf43 100644 --- a/vss-processor/src/main/kotlin/org/eclipse/kuksa/vssprocessor/spec/VssNodeSpecModel.kt +++ b/vss-processor/src/main/kotlin/org/eclipse/kuksa/vssprocessor/spec/VssNodeSpecModel.kt @@ -32,8 +32,9 @@ import com.squareup.kotlinpoet.TypeName import com.squareup.kotlinpoet.TypeSpec import com.squareup.kotlinpoet.asClassName import com.squareup.kotlinpoet.asTypeName -import org.eclipse.kuksa.vsscore.model.VssLeaf +import org.eclipse.kuksa.vsscore.model.VssBranch import org.eclipse.kuksa.vsscore.model.VssNode +import org.eclipse.kuksa.vsscore.model.VssSignal import org.eclipse.kuksa.vsscore.model.className import org.eclipse.kuksa.vsscore.model.name import org.eclipse.kuksa.vsscore.model.parentClassName @@ -113,7 +114,7 @@ internal class VssNodeSpecModel( val constructorBuilder = FunSpec.constructorBuilder() .addAnnotation(JvmOverloads::class) val propertySpecs = mutableListOf() - val superInterfaces = mutableSetOf(VssNode::class.asTypeName()) + val superInterfaces = mutableSetOf(VssBranch::class.asTypeName()) // The last element in the chain should have a value like "isLocked". if (childNodes.isEmpty()) { @@ -122,12 +123,12 @@ internal class VssNodeSpecModel( constructorBuilder.addParameter(parameterSpec) propertySpecs.add(valuePropertySpec) - // Final leafs should ONLY implement the vss property interface + // Final leafs should ONLY implement the VssSignal interface superInterfaces.clear() - val vssLeafInterface = VssLeaf::class + val vssSignalInterface = VssSignal::class .asTypeName() .plusParameter(datatypeProperty) - superInterfaces.add(vssLeafInterface) + superInterfaces.add(vssSignalInterface) } val propertySpec = createVssNodeSpecs(className, packageName = packageName) From 4975b33534339f2c381e8ff833b19e698a23bc70 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mark=20Hu=CC=88sers?= Date: Thu, 14 Mar 2024 13:18:56 +0100 Subject: [PATCH 19/20] chore: Fix missing child in heritage The filter was wrongly added to the method. --- .../main/kotlin/org/eclipse/kuksa/vsscore/model/VssNode.kt | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/vss-core/src/main/kotlin/org/eclipse/kuksa/vsscore/model/VssNode.kt b/vss-core/src/main/kotlin/org/eclipse/kuksa/vsscore/model/VssNode.kt index 378e3687..f0c6d0ad 100644 --- a/vss-core/src/main/kotlin/org/eclipse/kuksa/vsscore/model/VssNode.kt +++ b/vss-core/src/main/kotlin/org/eclipse/kuksa/vsscore/model/VssNode.kt @@ -146,9 +146,7 @@ val VssNode.parentClassName: String * big collection. */ val VssNode.heritage: Collection - get() = children.toList() + children - .filterIsInstance() - .flatMap { it.heritage } + get() = children.toList() + children.flatMap { it.heritage } /** * Finds the latest generation in the form of [VssSignal] for the current [VssNode]. From 35793078fd3a775e771dcc86f52afb5a959be8e4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mark=20Hu=CC=88sers?= Date: Thu, 14 Mar 2024 13:38:13 +0100 Subject: [PATCH 20/20] chore: Simplify filter logic for VssNode.findSignal() --- .../main/kotlin/org/eclipse/kuksa/vsscore/model/VssNode.kt | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/vss-core/src/main/kotlin/org/eclipse/kuksa/vsscore/model/VssNode.kt b/vss-core/src/main/kotlin/org/eclipse/kuksa/vsscore/model/VssNode.kt index f0c6d0ad..b613f616 100644 --- a/vss-core/src/main/kotlin/org/eclipse/kuksa/vsscore/model/VssNode.kt +++ b/vss-core/src/main/kotlin/org/eclipse/kuksa/vsscore/model/VssNode.kt @@ -223,9 +223,8 @@ fun VssNode.findHeritageLine( /** * Finds the given [signal] inside the current [VssNode]. */ -inline fun , V : Any> VssNode.findSignal(signal: T): T { +inline fun , V : Any> VssNode.findSignal(signal: T): VssNode { return heritage - .filterIsInstance() .first { it.uuid == signal.uuid } } @@ -233,9 +232,8 @@ inline fun , V : Any> VssNode.findSignal(signal: T): T * Finds all [VssSignal] which matches the given [KClass.simpleName]. This is useful when multiple nested objects * with the same Name exists but are pretty much the same besides the [VssNode.vssPath] etc. */ -inline fun , V : Any> VssNode.findSignal(type: KClass): Map { +inline fun , V : Any> VssNode.findSignal(type: KClass): Map { return heritage - .filterIsInstance() .filter { it::class.simpleName == type.simpleName } .associateBy { it.vssPath } }