Skip to content

Implement MQTT Topic Subscription in MqttManager (CATROID-1674) - #5233

Open
Paras-ydv wants to merge 2 commits into
Catrobat:developfrom
Paras-ydv:CATROID-1674
Open

Implement MQTT Topic Subscription in MqttManager (CATROID-1674)#5233
Paras-ydv wants to merge 2 commits into
Catrobat:developfrom
Paras-ydv:CATROID-1674

Conversation

@Paras-ydv

@Paras-ydv Paras-ydv commented Aug 7, 2026

Copy link
Copy Markdown
Contributor

Summary

Extends MqttManager to support subscribing to and unsubscribing from MQTT topics.

Dependency notice: this PR builds on CATROID-1673 (#5225), which is not merged yet, so that commit is included here to keep the branch buildable on its own. Please merge #5225 first; this branch will then be rebased and the commit will drop out by itself.

The branch previously also carried the dependency, settings and connection lifecycle commits. Those have since been merged (#5220, #5222), so the branch has been rebased onto develop and they are gone. Two commits remain.

This ticket is scoped to subscription management only. Handling the messages that arrive on a subscribed topic is a separate ticket.

CATROID-1674 — Subscribe implementation

Changes

  • Added subscribe(topic, qos) and unsubscribe(topic) to MqttClientInterface and implemented both in PahoMqttClient
  • MqttManager.subscribe() validates the topic is not blank and the QoS is in range 0–2. Unlike publish, the # and + wildcards are accepted here, since they are only legal in subscriptions
  • Active subscriptions are tracked in a Map<String, Int> of topic to QoS, exposed read-only as activeSubscriptions, and cleared on disconnect()
  • A duplicate subscribe returns true without calling the client again
  • Lazy-connects before subscribing when no connection is active
  • subscribeFromContext() convenience wrapper for the brick layer
  • unsubscribe() is idempotent and returns true when the topic was never subscribed
  • A failed subscribe does not record the topic, so the tracked state never claims a subscription the broker did not accept
  • Failures are logged and returned as false rather than thrown

Tests

29 new tests:

  • Subscribe succeeds and reaches the client with the correct topic and QoS
  • Wildcard topics accepted (# and +)
  • Blank topic rejected, and the client is not called
  • QoS 0 and 2 accepted; out-of-range QoS rejected
  • Duplicate subscribe returns true without re-calling the client, including with a different QoS
  • Lazy connect triggered when disconnected, and subscribe fails cleanly when that connect fails
  • Client exception returns false without crashing
  • A failed subscribe is not added to the tracked subscriptions
  • Unsubscribe succeeds with the correct topic and removes it from the tracked set
  • Unsubscribe on a topic that was never subscribed returns true without calling the client
  • Blank topic rejected on unsubscribe; client exception returns false without crashing
  • Subscriptions cleared on disconnect(), and subscribing works again afterwards

Full suite: 4709 tests, 0 failures.

A note on the rebase

Two existing tests were updated. MqttManager now takes an MqttClientFactory instead of a client instance, following the change made during the CATROID-1671 review, so tests that assumed an injected client have to connect first. Without that, testSubscribeAfterDisconnectSucceedsAgain did not compile.

The conflict in disconnect() was resolved in favour of the version on develop, which guards on mqttClient == null inside a synchronized block rather than on !isConnected, with subscriptions.clear() added into its finally. The null guard is the safer of the two, since it still cleans up when the connection has dropped but the client object is alive.

Acceptance criteria

  • subscribe() and unsubscribe() API added to MqttManager
  • Both methods added to MqttClientInterface and PahoMqttClient
  • Wildcard topics supported for subscriptions
  • Active subscriptions tracked and cleared on disconnect
  • Lazy connection established automatically if none exists
  • Configurable QoS per subscription
  • Failures logged without crashing
  • Unit tests covering the success paths, the validation rejections and the failure modes
  • All existing and new tests pass

Your Checklist

  • Include the name of the Jira ticket in the PR's title
  • Include a summary of the changes plus the relevant context
  • Choose the proper base branch (develop)
  • Confirm that the changes follow the project's coding guidelines
  • Verify that the changes generate no compiler or linter warnings
  • Perform a self-review of the changes
  • Verify to commit no other files than the intentionally changed ones
  • Include reasonable and readable tests verifying the added or changed behavior
  • Confirm that new and existing unit tests pass locally
  • Check that the commits' message style matches the project's guideline
  • Stick to the project's gitflow workflow
  • Verify that your changes do not have any conflicts with the base branch
  • After the PR, verify that all CI checks have passed
  • Post a message in the catroid-stage or catroid-ide Slack channel and ask for a code reviewer

@harshsomankar123-tech
harshsomankar123-tech marked this pull request as draft August 8, 2026 15:11
@Paras-ydv
Paras-ydv marked this pull request as ready for review August 9, 2026 11:40
@Paras-ydv
Paras-ydv marked this pull request as draft August 9, 2026 11:40
@reichli reichli added Active Member Tickets that are assigned to members that are still currently active GSoC-2026 This ticket is assigned to the GSoC contributor. and removed Active Member Tickets that are assigned to members that are still currently active labels Aug 19, 2026
- Add publish() to MqttClientInterface and PahoMqttClient
- Implement publish() in MqttManager with topic validation (blank,
  wildcards), QoS range check (0-2), and retained flag support
- Lazy-connect before publishing if no active connection exists
- Rename publishFromContext() to avoid Detekt MethodOverloading
- Log failures without crashing; no forced unwrap
- Add comprehensive unit tests: empty payload, QoS boundaries,
  retained flag, lazy connect, no reconnect when already connected,
  no publish when connect fails (51 tests total)
@sonarqubecloud

sonarqubecloud Bot commented Sep 2, 2026

Copy link
Copy Markdown

@Paras-ydv
Paras-ydv marked this pull request as ready for review September 2, 2026 16:07
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

GSoC-2026 This ticket is assigned to the GSoC contributor.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants