neiam
/apollos_crib
It's Apollo's Crib
public · Issues · Pulls 1 · Labels · Forks · Compare · Actions failure · Badges · Packages
⭐
Log in to mark this repository.
Recognise the Plus board by the topic RabbitMQ actually delivers
e996024 · Gabriel Morell · 2026-09-08 20:09
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