Skip to content

MQTT: configure the will message, the MQTT 5.0 connect limits and the responses - #3544

Open
dometec wants to merge 3 commits into
smallrye:mainfrom
dometec:mqtt5_on_vertx51
Open

dometec wants to merge 3 commits into
smallrye:mainfrom
dometec:mqtt5_on_vertx51

Conversation

@dometec

@dometec dometec commented Sep 25, 2026

Copy link
Copy Markdown
Contributor

Completes the MQTT 5.0 support that came with the Vert.x 5 switch (#3492) with the parts the
connector cannot express yet, and fixes two things found on the way.

Last Will and Testament

will-flag, will-qos and will-retain were the only will attributes, so the will message
itself — its topic and its payload — could not be configured at all: it could only come from a
custom MqttClientSessionOptions bean. The channel now accepts:

  • will-topic and will-payload, which must be set together — the connector fails to start when
    only one of them is set, since the broker never sends such a will message;
  • will-content-type, will-response-topic and will-delay-interval for MQTT 5.0.

While doing this: will-flag has had no effect since the Vert.x 5 client stopped exposing
setWillFlag() and derives the flag from the will message itself. It is now documented as
ignored, and kept accepted so that existing configurations keep working. Tell me if you would
rather deprecate or remove it.

MQTT 5.0 connect properties

receive-maximum and topic-alias-maximum are exposed as channel attributes, next to the
existing session-expiry-interval and authentication-method.

Request/response

MQTT 5.0 carries request/response interactions with the Response Topic and Correlation Data
properties. MqttMessage.ofResponse(request, payload, qos[, userProperties]) builds the reply:
it sends the message on the topic the requester asked for and copies the correlation data, so the
requester can match the two. MqttMessage also exposes getResponseTopic() and
getCorrelationData(), so replying does not require reading the metadata.

Fixes

  • will-qos was looked up as "will-qus" in MqttHelpers.customize(), so setting it on a
    channel that also uses a custom options bean had no effect.

  • retain-handling travelled as a raw int down to the subscription, where Netty turned it into
    a RetainedHandlingPolicy: an out-of-range value failed late, inside the subscription, with a
    message naming neither the channel nor the attribute, and the logs only showed
    Subscription failed!. It is converted once, when the channel is created, and the policy
    itself is carried through SubscriptionOptions and the subscribe() methods of
    MqttClientSession.

    This changes two public signatures: MqttClientSession.subscribe(..., RetainedHandlingPolicy retainHandling[, Integer subscriptionIdentifier]) and the SubscriptionOptions constructors
    take the policy instead of an int. They were introduced by Switch to Vert.x 5 #3492 and, as far as I can see, are
    not in a release yet, so this seemed the right moment — happy to keep the int overloads
    instead if you prefer.

Documentation

The connector documentation still declared that no inbound nor outbound metadata is provided,
which stopped being true when the v5 metadata landed. Both sections are written, together with the
protocol version, the last will and the request/response example.

Testing

mvn test on the MQTT module: 181 tests, no failure. The new ones are four on
MqttMessage.ofResponse(...) in MqttMessageTest and three on the retain-handling conversion
in MqttHelpersTest.

About #3477

This PR targets main, so it builds on the Vert.x 5 client. I am keeping my mqtt5 branch,
which is based on the 4.x line, and #3477 with it: I do not know whether vertx-mqtt 4.x will get
MQTT 5.0 (vert-x3/vertx-mqtt#269) support, and until that is clear I would rather not drop the work that carries these features there.

@codecov

codecov Bot commented Sep 25, 2026 •

Copy link
Copy Markdown

Codecov Report

❌ Patch coverage is 35.84906% with 34 lines in your changes missing coverage. Please review.
✅ Project coverage is 75.88%. Comparing base (a96442f) to head (a4c2a0a).
⚠️ Report is 1277 commits behind head on main.

Files with missing lines Patch % Lines
.../reactive/messaging/mqtt/internal/MqttHelpers.java 17.24% 15 Missing and 9 partials ⚠️
.../smallrye/reactive/messaging/mqtt/MqttMessage.java 64.70% 6 Missing ⚠️
...ve/messaging/mqtt/session/SubscriptionOptions.java 50.00% 0 Missing and 2 partials ⚠️
...o/smallrye/reactive/messaging/mqtt/MqttSource.java 50.00% 0 Missing and 1 partial ⚠️
...aging/mqtt/session/impl/MqttClientSessionImpl.java 0.00% 1 Missing ⚠️
Additional details and impacted files

Impacted file tree graph

@@             Coverage Diff              @@
##               main    #3544      +/-   ##
============================================
- Coverage     77.47%   75.88%   -1.59%     
- Complexity     3778     5282    +1504     
============================================
  Files           306      455     +149     
  Lines         12673    18078    +5405     
  Branches       1648     2265     +617     
============================================
+ Hits           9818    13718    +3900     
- Misses         2116     3250    +1134     
- Partials        739     1110     +371     
Files with missing lines Coverage Δ
...mallrye/reactive/messaging/mqtt/MqttConnector.java 100.00% <ø> (ø)
...e/reactive/messaging/mqtt/i18n/MqttExceptions.java 100.00% <ø> (ø)
...tive/messaging/mqtt/session/MqttClientSession.java 50.00% <ø> (-16.67%) ⬇️
...o/smallrye/reactive/messaging/mqtt/MqttSource.java 71.05% <50.00%> (-8.32%) ⬇️
...aging/mqtt/session/impl/MqttClientSessionImpl.java 58.49% <0.00%> (+4.91%) ⬆️
...ve/messaging/mqtt/session/SubscriptionOptions.java 52.94% <50.00%> (ø)
.../smallrye/reactive/messaging/mqtt/MqttMessage.java 68.00% <64.70%> (-7.00%) ⬇️
.../reactive/messaging/mqtt/internal/MqttHelpers.java 46.99% <17.24%> (-4.73%) ⬇️

... and 327 files with indirect coverage changes

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.

dometec and others added 3 commits November 2, 2026 17:40
…nses

Complete the MQTT 5.0 support with what the connector could not express yet:

* The last will message can be configured on the channel: will-topic and
  will-payload, plus will-content-type, will-response-topic and
  will-delay-interval for MQTT 5.0. The connector fails to start when only one
  of will-topic and will-payload is set, since the broker never sends such a
  will message.
* The connect properties receive-maximum and topic-alias-maximum are exposed.
* MqttMessage.ofResponse() builds the reply to an MQTT 5.0 request: it sends the
  message on the Response Topic carried by the request and copies its
  Correlation Data. MqttMessage also exposes getResponseTopic() and
  getCorrelationData(), so that replying does not require reading the metadata.

Also fix the will-qos attribute, which was looked up as "will-qus" and so was
ignored when customizing the options of a channel, and document the inbound and
outbound metadata, which the documentation still declared as not provided.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
The attribute has had no effect since the switch to Vert.x 5, whose MQTT client
derives the will flag from the will message instead of exposing setWillFlag().
It stays accepted so that existing configurations keep working.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
The `retain-handling` attribute travelled as a raw int down to the subscription,
where Netty turned it into a RetainedHandlingPolicy: an out-of-range value
failed late, inside the subscription, with a message naming neither the channel
nor the attribute.

Convert it once, when the channel is created, and carry the policy itself
through SubscriptionOptions and the subscribe() methods of MqttClientSession. An
invalid value now fails the channel immediately, saying which channel and which
values are allowed.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>

This branch has not been deployed

No deployments
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant