Skip to content

Commit 7dcc7cd

Browse files
author
paulwinter
committed
feat: add ChangeZoneMetadataValue command and test (#163)
1 parent 425ae19 commit 7dcc7cd

9 files changed

Lines changed: 179 additions & 2 deletions

File tree

xesar-connect/src/main/kotlin/com/open200/xesar/connect/Topics.kt

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -480,6 +480,9 @@ class Topics(vararg val topics: String) {
480480

481481
/** MQTT topic string for the "ChangePersonMetadataValueMapi" command. */
482482
val CHANGE_PERSON_METADATA_VALUE = "xs3/1/cmd/ChangePersonMetadataValueMapi"
483+
484+
/** MQTT topic string for the "ChangeZoneMetadataValueMapi" command. */
485+
val CHANGE_ZONE_METADATA_VALUE = "xs3/1/cmd/ChangeZoneMetadataValueMapi"
483486
}
484487
}
485488

xesar-connect/src/main/kotlin/com/open200/xesar/connect/extension/XesarConnectZoneExt.kt

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -167,6 +167,35 @@ suspend fun XesarConnect.removeInstallationPointFromZoneAsync(
167167
)
168168
}
169169

170+
/**
171+
* Changes the value of custom data field of a zone.
172+
*
173+
* @param id The ID of the zone.
174+
* @param metadataId The metadataID of the data field.
175+
* @param value The new value of the field.
176+
* @param requestConfig The request configuration (optional).
177+
*/
178+
suspend fun XesarConnect.changeZoneMetadataValueAsync(
179+
id: UUID,
180+
metadataId: UUID,
181+
value: String,
182+
requestConfig: XesarConnect.RequestConfig = buildRequestConfig(),
183+
): SingleEventResult<ZoneChanged> {
184+
return sendCommandAsync<ChangeZoneMetadataValueMapi, ZoneChanged>(
185+
Topics.Command.CHANGE_ZONE_METADATA_VALUE,
186+
Topics.Event.ZONE_CHANGED,
187+
true,
188+
ChangeZoneMetadataValueMapi(
189+
config.uuidGenerator.generateId(),
190+
id,
191+
metadataId,
192+
value,
193+
token,
194+
),
195+
requestConfig,
196+
)
197+
}
198+
170199
/**
171200
* Retrieves a cold stream of [Zone] objects, fetching them incrementally in smaller,more manageable
172201
* chunks rather than retrieving the entire dataset at once. Use [Query.Params.pageLimit] to choose
Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
package com.open200.xesar.connect.messages.command
2+
3+
import com.open200.xesar.connect.utils.UUIDSerializer
4+
import java.util.*
5+
import kotlinx.serialization.Serializable
6+
7+
/**
8+
* Represents a command POJO to change a custom data field value for a zone.
9+
*
10+
* @param commandId The id of the command.
11+
* @param id The id of the zone.
12+
* @param metadataId The id of the custom data field.
13+
* @param value The new value of the custom data field.
14+
* @param token The token of the command.
15+
*/
16+
@Serializable
17+
data class ChangeZoneMetadataValueMapi(
18+
override val commandId: @Serializable(with = UUIDSerializer::class) UUID,
19+
val id: @Serializable(with = UUIDSerializer::class) UUID,
20+
val metadataId: @Serializable(with = UUIDSerializer::class) UUID,
21+
val value: String,
22+
val token: String,
23+
) : Command

xesar-connect/src/main/kotlin/com/open200/xesar/connect/messages/event/ZoneChanged.kt

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
package com.open200.xesar.connect.messages.event
22

3+
import com.open200.xesar.connect.messages.EntityMetadata
34
import com.open200.xesar.connect.utils.UUIDSerializer
45
import java.util.*
56
import kotlinx.serialization.Serializable
@@ -10,10 +11,12 @@ import kotlinx.serialization.Serializable
1011
* @param name The name of the zone.
1112
* @param description The description of the zone.
1213
* @param id The id of the zone.
14+
* @param entityMetadata Contains the information for all defined custom data fields for the zone.
1315
*/
1416
@Serializable
1517
data class ZoneChanged(
1618
val name: String,
1719
val description: String,
1820
@Serializable(with = UUIDSerializer::class) val id: UUID,
21+
val entityMetadata: List<EntityMetadata>? = null,
1922
) : Event

xesar-connect/src/main/kotlin/com/open200/xesar/connect/messages/query/Zone.kt

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,22 @@
11
package com.open200.xesar.connect.messages.query
22

3+
import com.open200.xesar.connect.messages.EntityMetadata
34
import com.open200.xesar.connect.utils.UUIDSerializer
45
import java.util.*
56
import kotlinx.serialization.Serializable
67

8+
/**
9+
* Represents a zone.
10+
*
11+
* @param installationPoints The list of installation points of the zone (optional).
12+
* @param partitionId The partition identifier of the zone.
13+
* @param installationPointCount The installationPointCount of the zone (optional).
14+
* @param name The name of the zone.
15+
* @param description The description of the zone (optional).
16+
* @param id The id of the zone.
17+
* @param entityMetadata Contains the information for all defined custom data fields for the zone
18+
* (optional).
19+
*/
720
@Serializable
821
data class Zone(
922
val installationPoints: List<@Serializable(with = UUIDSerializer::class) UUID> = emptyList(),
@@ -12,6 +25,7 @@ data class Zone(
1225
val name: String,
1326
val description: String? = null,
1427
@Serializable(with = UUIDSerializer::class) val id: UUID,
28+
val entityMetadata: List<EntityMetadata>? = null,
1529
) : QueryListResource, QueryElementResource {
1630

1731
companion object {

xesar-connect/src/test/kotlin/com/open200/xesar/connect/encodingDecoding/query/ZoneElementTest.kt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@ class ZoneElementTest :
1616
)
1717

1818
val zoneString =
19-
"{\"requestId\":\"d385ab22-0f51-4b97-9ecd-b8ff3fd4fcb6\",\"response\":{\"installationPoints\":[\"7ca59670-bd30-4ea9-9bd1-2103a9bd2f2a\"],\"partitionId\":\"7b4399a0-21ce-4bee-ba43-e06e291248d2\",\"installationPointCount\":0,\"name\":\"zone name\",\"description\":\"zone description\",\"id\":\"497f6eca-6276-4993-bfeb-53cbbbba6f08\"}}"
19+
"{\"requestId\":\"d385ab22-0f51-4b97-9ecd-b8ff3fd4fcb6\",\"response\":{\"installationPoints\":[\"7ca59670-bd30-4ea9-9bd1-2103a9bd2f2a\"],\"partitionId\":\"7b4399a0-21ce-4bee-ba43-e06e291248d2\",\"installationPointCount\":0,\"name\":\"zone name\",\"description\":\"zone description\",\"id\":\"497f6eca-6276-4993-bfeb-53cbbbba6f08\",\"entityMetadata\":[]}}"
2020

2121
test("encoding QueryElement for a zone") {
2222
val zoneEncoded = encodeQueryElement(zone)

xesar-connect/src/test/kotlin/com/open200/xesar/connect/encodingDecoding/query/ZoneListTest.kt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -33,7 +33,7 @@ class ZoneListTest :
3333
)
3434

3535
val zoneString =
36-
"{\"requestId\":\"00000000-1281-40ae-89d7-5c541d77a757\",\"response\":{\"data\":[{\"installationPoints\":[\"7ca59670-bd30-4ea9-9bd1-2103a9bd2f2a\"],\"partitionId\":\"7b4399a0-21ce-4bee-ba43-e06e291248d2\",\"installationPointCount\":0,\"name\":\"zone name\",\"description\":\"zone description\",\"id\":\"497f6eca-6276-4993-bfeb-53cbbbba6f08\"},{\"installationPoints\":[\"7ca59670-bd30-4ea9-9bd1-2103a9bd2f2a\",\"f6a5bdf2-7c7d-11ee-b962-0242ac120002\"],\"partitionId\":\"7b4399a0-21ce-4bee-ba43-e06e291248d2\",\"installationPointCount\":0,\"name\":\"zone name\",\"description\":\"zone description\",\"id\":\"a4c838a8-f6be-49e0-abee-c1d3b2897279\"}],\"totalCount\":2,\"filterCount\":2}}"
36+
"{\"requestId\":\"00000000-1281-40ae-89d7-5c541d77a757\",\"response\":{\"data\":[{\"installationPoints\":[\"7ca59670-bd30-4ea9-9bd1-2103a9bd2f2a\"],\"partitionId\":\"7b4399a0-21ce-4bee-ba43-e06e291248d2\",\"installationPointCount\":0,\"name\":\"zone name\",\"description\":\"zone description\",\"id\":\"497f6eca-6276-4993-bfeb-53cbbbba6f08\",\"entityMetadata\":[]},{\"installationPoints\":[\"7ca59670-bd30-4ea9-9bd1-2103a9bd2f2a\",\"f6a5bdf2-7c7d-11ee-b962-0242ac120002\"],\"partitionId\":\"7b4399a0-21ce-4bee-ba43-e06e291248d2\",\"installationPointCount\":0,\"name\":\"zone name\",\"description\":\"zone description\",\"id\":\"a4c838a8-f6be-49e0-abee-c1d3b2897279\",\"entityMetadata\":[]}],\"totalCount\":2,\"filterCount\":2}}"
3737

3838
test("encoding QueryList for a list of zones") {
3939
val zoneEncoded = encodeQueryList(zoneList)
Lines changed: 104 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,104 @@
1+
package com.open200.xesar.connect.it.command
2+
3+
import com.open200.xesar.connect.Topics
4+
import com.open200.xesar.connect.XesarConnect
5+
import com.open200.xesar.connect.XesarMqttClient
6+
import com.open200.xesar.connect.extension.changeZoneMetadataValueAsync
7+
import com.open200.xesar.connect.it.MosquittoContainer
8+
import com.open200.xesar.connect.messages.EntityMetadata
9+
import com.open200.xesar.connect.messages.event.ApiEvent
10+
import com.open200.xesar.connect.messages.event.ZoneChanged
11+
import com.open200.xesar.connect.messages.event.encodeEvent
12+
import io.kotest.common.runBlocking
13+
import io.kotest.core.spec.style.FunSpec
14+
import io.kotest.extensions.testcontainers.perProject
15+
import io.kotest.matchers.equals.shouldBeEqual
16+
import io.mockk.coEvery
17+
import java.util.*
18+
import kotlinx.coroutines.CompletableDeferred
19+
import kotlinx.coroutines.launch
20+
21+
class ChangeZoneMetadataValueTest :
22+
FunSpec({
23+
val container = MosquittoContainer.container()
24+
val config = MosquittoContainer.config(container)
25+
listener(container.perProject())
26+
27+
test("change zone metadata value") {
28+
coEvery { config.uuidGenerator.generateId() }
29+
.returns(UUID.fromString("00000000-1281-40ae-89d7-5c541d77a757"))
30+
31+
val zoneId = UUID.fromString("11111111-2222-3333-4444-555555555555")
32+
val metadataId = UUID.fromString("aaaaaaaa-0000-0000-0000-000000000001")
33+
34+
runBlocking {
35+
val simulatedBackendReady = CompletableDeferred<Unit>()
36+
val commandReceived = CompletableDeferred<String>()
37+
38+
launch {
39+
XesarMqttClient.connectAsync(config).await().use { client ->
40+
client.subscribeAsync(arrayOf(Topics.ALL_TOPICS)).await()
41+
42+
client.onMessage = { topic, payload ->
43+
when (topic) {
44+
Topics.Command.CHANGE_ZONE_METADATA_VALUE -> {
45+
commandReceived.complete(payload.decodeToString())
46+
}
47+
}
48+
}
49+
50+
simulatedBackendReady.complete(Unit)
51+
52+
val commandContent = commandReceived.await()
53+
54+
commandContent.shouldBeEqual(
55+
"{\"commandId\":\"00000000-1281-40ae-89d7-5c541d77a757\",\"id\":\"11111111-2222-3333-4444-555555555555\",\"metadataId\":\"aaaaaaaa-0000-0000-0000-000000000001\",\"value\":\"Top Secret\",\"token\":\"JDJhJDEwJDFSNEljZ2FaRUNXUXBTQ25XN05KbE9qRzFHQ1VjMzkvWTBVcFpZb1M4Vmt0dnJYZ0tJVFBx\"}"
56+
)
57+
58+
val apiEvent =
59+
ApiEvent(
60+
UUID.fromString("00000000-1281-40ae-89d7-5c541d77a757"),
61+
ZoneChanged(
62+
name = "Test Zone",
63+
description = "Test Description",
64+
id = zoneId,
65+
entityMetadata =
66+
listOf(
67+
EntityMetadata(
68+
id = metadataId,
69+
name = "security clearance required",
70+
value = "Top Secret",
71+
)
72+
),
73+
),
74+
)
75+
76+
client
77+
.publishAsync(Topics.Event.ZONE_CHANGED, encodeEvent(apiEvent))
78+
.await()
79+
}
80+
}
81+
82+
launch {
83+
simulatedBackendReady.await()
84+
85+
val api = XesarConnect.connectAndLoginAsync(config).await()
86+
api.subscribeAsync(Topics(Topics.Event.ZONE_CHANGED)).await()
87+
88+
val result =
89+
api.changeZoneMetadataValueAsync(
90+
id = zoneId,
91+
metadataId = metadataId,
92+
value = "Top Secret",
93+
)
94+
.await()
95+
96+
result.id.shouldBeEqual(zoneId)
97+
result.entityMetadata!!
98+
.single { it.id == metadataId }
99+
.value
100+
?.shouldBeEqual("Top Secret")
101+
}
102+
}
103+
}
104+
})

xesar-connect/src/test/kotlin/com/open200/xesar/connect/util/fixture/ZoneFixture.kt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,5 +13,6 @@ object ZoneFixture {
1313
description = "zone description",
1414
id = UUID.fromString("497f6eca-6276-4993-bfeb-53cbbbba6f08"),
1515
installationPoints = listOf(UUID.fromString("7ca59670-bd30-4ea9-9bd1-2103a9bd2f2a")),
16+
entityMetadata = emptyList(),
1617
)
1718
}

0 commit comments

Comments
 (0)