Recognise the Plus board by the topic RabbitMQ actually delivers

e996024 · Gabriel Morell · 2026-09-08 20:09

18 files +58 -1
Message
{commit_body(@commit)}

Files changed

modified clients/android/app/src/main/java/io/neiam/apolloscrib/mqtt/AnkyraClient.kt
+18 −1
@@ -125,7 +125,7 @@ class AnkyraClient(
125 125 // at the payload: the two boards carry the same query ids and
126 126 // mostly the same types, and guessing from content would be
127 127 // guessing.
128 − if (publish.topic.toString().endsWith(PLUS_SUFFIX)) {
128 + if (isPlusTopic(publish.topic.toString())) {
129 129 onPlus(payload)
130 130 } else {
131 131 onMessage(payload)
@@ -229,5 +229,22 @@ class AnkyraClient(
229 229
230 230 /** Where a Pythiae publishes its Plus reading, beside the Basic one. */
231 231 const val PLUS_SUFFIX = ".plus"
232 +
233 + /**
234 + * Whether a delivered topic is the Plus one.
235 + *
236 + * The separator changes in flight. A Pythiae publishes to the AMQP
237 + * routing key `<topic>.plus`, and RabbitMQ's MQTT plugin maps dots in
238 + * a routing key to slashes in the topic it hands a subscriber -- so
239 + * what is subscribed to as `X.plus` arrives as `X/plus`.
240 + *
241 + * It went unnoticed because both boards still arrived: the Plus one
242 + * simply failed this test and was filed as the Basic board, which then
243 + * lost most of its cards, because nothing draws a `gtfs_plus` entry in
244 + * compact mode. Two boards alternating in the log at slightly
245 + * different sizes is what gave it away.
246 + */
247 + fun isPlusTopic(topic: String): Boolean =
248 + topic.replace('/', '.').endsWith(PLUS_SUFFIX)
232 249 }
233 250 }
added clients/android/app/src/test/java/io/neiam/apolloscrib/mqtt/TopicTest.kt
+40 −0
@@ -0,0 +1,40 @@
1 +package io.neiam.apolloscrib.mqtt
2 +
3 +import org.junit.Assert.assertFalse
4 +import org.junit.Assert.assertTrue
5 +import org.junit.Test
6 +
7 +/**
8 + * Which board a message is, from the topic it arrived on.
9 + *
10 + * The separator changes in flight: a Pythiae publishes to the AMQP routing key
11 + * `<topic>.plus`, and RabbitMQ's MQTT plugin hands it to a subscriber as
12 + * `<topic>/plus`. Both spellings have to read as the same thing.
13 + */
14 +class TopicTest {
15 +
16 + @Test
17 + fun `the plus board as RabbitMQ delivers it`() {
18 + assertTrue(AnkyraClient.isPlusTopic("Iodized-Nutritious-Xenoposeidon/plus"))
19 + }
20 +
21 + @Test
22 + fun `the plus board as it is subscribed to`() {
23 + assertTrue(AnkyraClient.isPlusTopic("Iodized-Nutritious-Xenoposeidon.plus"))
24 + }
25 +
26 + @Test
27 + fun `the ordinary board is not the plus one`() {
28 + assertFalse(AnkyraClient.isPlusTopic("Iodized-Nutritious-Xenoposeidon"))
29 + }
30 +
31 + @Test
32 + fun `a topic that merely mentions plus is not the plus board`() {
33 + assertFalse(AnkyraClient.isPlusTopic("Plus-Nutritious-Xenoposeidon"))
34 + }
35 +
36 + @Test
37 + fun `an uplink is not a board at all`() {
38 + assertFalse(AnkyraClient.isPlusTopic("Iodized-Nutritious-Xenoposeidon/up/loc"))
39 + }
40 +}

Parents: 725a8da