How to get the topic name in a SubackOutboundInterceptor

I’d like to generate several Publish message(s) to a specific topic in response to a successful subscription to that same specific topic. Right now I’ve created an extension that implements the SubackOutboundInterceptor interface. It works, but I have to hard code the topic name in the publish message.

Is there any way to access the name of the topic in the related to the Suback message in this context?

@Override
    public void onOutboundSuback(@NotNull SubackOutboundInput subackOutboundInput,
            @NotNull SubackOutboundOutput subackOutboundOutput) {
       
            final SubackPacket subackPacket = subackOutboundInput.getSubackPacket();
            SubackReasonCode firstReasonCode = subackPacket.getReasonCodes().get(0);            

            // make sure the reason code of the response is one of the GRANTED flavors

            if(firstReasonCode.equals(SubackReasonCode.GRANTED_QOS_0) ||
                    firstReasonCode.equals(SubackReasonCode.GRANTED_QOS_1) ||
                        firstReasonCode.equals(SubackReasonCode.GRANTED_QOS_2)) {

                    final PublishService publishService = Services.publishService();
                    final ByteBuffer payload = ByteBuffer.wrap("My Sample Message".getBytes());

                    Publish message = Builders.publish()
                            .topic("user/c2ace553-0959-4bce-b674-0c7ca015dc02") // <----- HOW TO DERIVE HIS FROM THE SubackPacket
                            .payload(payload)
                            .build();

                    final CompletableFuture<Void> future = publishService.publish(message);

                    future.whenComplete((aVoid, throwable) -> {
                        if (throwable == null) {
                            System.out.println("Publish sent successfully");
                        } else {
                            //please use more sophisticated logging
                            throwable.printStackTrace();
                        }
                    });

            }
}

Hi @lqsantacruz,

Thank you for your inquiry. In the context of the SubackOutboundInterceptor interface, the MQTT specification does not provide a direct means to access the topic name from the Suback message.

According to the MQTT specification, the SUBACK packet does not contain a topic field. The SUBACK packet is sent by the server in response to a SUBSCRIBE packet from the client. It acknowledges the client’s subscription request and indicates the maximum QoS level that the server has granted for each requested subscription.

The format of the SUBACK packet is as follows:

  • Fixed Header:
    • Control Packet Type: SUBACK (0x09)
    • Remaining Length
  • Variable Header:
    • Packet Identifier
  • Payload:
    • List of Subscription Return Codes

Each Subscription Return Code in the payload corresponds to a subscription topic requested by the client. The order of the return codes in the SUBACK payload corresponds to the order of the topics in the SUBSCRIBE packet sent by the client.

The SUBACK packet doesn’t include information about the topics themselves; it only provides return codes indicating the server’s acceptance or rejection of the client’s subscription requests.

Therefore, in the provided code snippet, the comment “HOW TO DERIVE THIS FROM THE SubackPacket” seems to suggest a misunderstanding or a potential error, as there is no direct way to derive a topic from a SUBACK packet according to the MQTT specification. Topics are specified in SUBSCRIBE and PUBLISH packets, not in SUBACK packets.

If you have specific questions related to this topic or need further clarification, please feel free to ask.

Best regards,
Dasha from HiveMQ Team

OK, thanks for the detailed explanation, I’ll try to find another way to implement what I’m looking for using other means.