Skip to content

Add MQTT message payload compression and decompression functionality#26

Open
KAVINDYADEVINDI wants to merge 2 commits into
entgra:masterfrom
KAVINDYADEVINDI:master
Open

Add MQTT message payload compression and decompression functionality#26
KAVINDYADEVINDI wants to merge 2 commits into
entgra:masterfrom
KAVINDYADEVINDI:master

Conversation

@KAVINDYADEVINDI

Copy link
Copy Markdown
Contributor

Purpose

To improve MQTT message reliability and performance.

  • Handle incoming MQTT messages safely by adding validations to prevent runtime exceptions during message arrival and processing.
  • Reduce MQTT payload size, preventing possible message payload loss or truncation when transmitting large payloads

Related Prs: entgra/device-mgt-core#170
Related Issue ticket: https://roadmap.entgra.net/issues/15144

Approach

  • Automatically compress MQTT payloads larger than 4 KB before transmission to reduce mqtt message.
  • Use GZIP compression (level 1) to achieve a balance between compression speed and size optimization.
  • Detect compressed messages on the receiver side by searching the payload for GZIP magic bytes (0x1f, 0x8b).
  • Support decompression even when compressed data is embedded within mixed or prefixed payload content.
  • Maintain backward compatibility with both:
  • plain JSON messages, and
  • compressed MQTT payloads.
  • Implement reusable utility methods for compression and decompression logic to improve maintainability.
  • Add validation and error handling to prevent runtime failures during message processing.
  • Include debug logging to simplify troubleshooting and payload inspection.
  • Add configured compression atributes from cdm

log.warn("Empty MqttMessage Received");
return;
}
int startIndex = mqttMsgString.indexOf("{");

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The current implementation relies on indexOf/lastIndexOf to extract JSON, which is not a safe parsing strategy.
This can lead to incorrect extraction when payloads contain additional braces or non-JSON content. Recommend using a proper JSON parsing library (e.g:- Jackson) to validate and deserialize the payload instead of manual string manipulation.

}
}

public static int findGzipHeaderOffset(byte[] payload) {

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Add Java Doc comment

return -1;
}

public static String decompressMqttMsgFromOffset(byte[] payload, int offset) throws IOException {

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Add Java Doc comment

}
}

public static byte[] compressMqttMessage(byte[] data) throws IOException {

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Add Java Doc comment

org.wso2.carbon.event.output.adapter.core.exception;version="[5.3,6)",
org.wso2.carbon.user.api;version="[1.0,2)"
org.wso2.carbon.user.api;version="[1.0,2)",
io.entgra.device.mgt.core.device.mgt.core.config;version="[5.2,6)",

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Don't hard code device-mgt core version, instead of add "${io.entgra.device.mgt.core.version.range}"


public static int findGzipHeaderOffset(byte[] payload) {
// Find the offset of the gzip header (gzip magic bytes -> 0x1f 0x8b)
for (int i = 0; i < payload.length - 1; i++) {

@IsuriSuhara27 IsuriSuhara27 Mar 3, 2026

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Maintain backward compatibility with both:
plain JSON messages, and
compressed MQTT payloads.

How is this achieved?, Instead of only using 4KB size to automatically use gzip compression, there need to be a variable to completely enable or disable gzip compression in device mgt core , cdm-config.xml and that need to be used here. Only the existing deployments relying on this listeners can then be safely tested for when gzip compression is enabled or disabled, otherwise when payload size is above the mentioned 4kb , gzip compression is forced.

int compressionThresholdKb = (configuredThresholdKb > 0) ? configuredThresholdKb :
DEFAULT_COMPRESSION_THRESHOLD_KB;

if (rawBytes.length >= compressionThresholdKb * 1024) {

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Add Constant for Byte Conversion

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.

5 participants