feature: [34] Implement TLS connection#171
Conversation
Test Coverage Report
|
There was a problem hiding this comment.
Pull request overview
This PR introduces end-to-end TLS support for the MQTT broker, spanning the network transport (TLS connection + SSL packet reader/writer), Spring Boot application configuration, and integration tests to validate secure client communication.
Changes:
- Added TLS transport implementation (
TlsMqttConnection, TLS reader/writer) and configuration model (TlsProperties). - Refactored packet parsing by extracting
MqttPacketCreatorand splitting plain vs TLS message readers/writers. - Added Spring configuration and integration tests to bootstrap a TLS listener and verify MQTT 3.1.1 / MQTT 5 communication over TLS.
Reviewed changes
Copilot reviewed 37 out of 38 changed files in this pull request and generated 9 comments.
Show a summary per file
| File | Description |
|---|---|
| test-support/src/main/groovy/javasabr/mqtt/test/support/TestSslContexts.groovy | Generates temporary keystores/truststores for TLS tests. |
| network/src/test/groovy/javasabr/mqtt/network/TlsMqttConnectionTest.groovy | Adds a basic TLS connection construction test. |
| network/src/test/groovy/javasabr/mqtt/network/message/PlainMqttMessageReaderTest.groovy | Adds a regression test for incomplete MBI handling. |
| network/src/main/java/javasabr/mqtt/network/TlsProperties.java | Introduces validated TLS configuration record. |
| network/src/main/java/javasabr/mqtt/network/TlsMqttConnection.java | Adds TLS-backed MQTT connection implementation. |
| network/src/main/java/javasabr/mqtt/network/MqttConnectionFactory.java | Generalizes connection factory with generics. |
| network/src/main/java/javasabr/mqtt/network/MqttConnection.java | Refactors to use MqttPacketCreator + plain reader/writer; improves close logging. |
| network/src/main/java/javasabr/mqtt/network/message/ssl/TlsMqttMessageWriter.java | Implements SSL-aware writer for MQTT packets. |
| network/src/main/java/javasabr/mqtt/network/message/ssl/TlsMqttMessageReader.java | Implements SSL-aware reader for MQTT packets. |
| network/src/main/java/javasabr/mqtt/network/message/ssl/package-info.java | Adds @NullMarked package annotation for ssl message package. |
| network/src/main/java/javasabr/mqtt/network/message/plain/PlainMqttMessageWriter.java | Renames/moves plain writer into dedicated package. |
| network/src/main/java/javasabr/mqtt/network/message/plain/PlainMqttMessageReader.java | Introduces plain reader using shared MqttPacketCreator. |
| network/src/main/java/javasabr/mqtt/network/message/MqttPacketCreator.java | Extracts packet length parsing + packet instantiation logic. |
| network/src/main/java/javasabr/mqtt/network/message/MqttMessageReader.java | Removes old reader (logic moved into creator + plain reader). |
| network/src/main/java/javasabr/mqtt/network/exception/TlsProtocolException.java | Adds TLS-specific runtime exception wrapper. |
| network/build.gradle | Adjusts network module dependencies (logging deps moved to convention). |
| gradle/libs.versions.toml | Bumps RLib + HiveMQ client versions. |
| embedded/build.gradle | Removes explicit logging dependency (moved to convention). |
| credentials-source-db/src/main/java/javasabr/mqtt/auth/credentials/source/DatabaseCredentialsSource.java | Switches debug output/toString to DebugUtils JSON representation. |
| core-service/src/test/groovy/javasabr/mqtt/service/IntegrationServiceSpecification.groovy | Updates test setup to supply MqttPacketCreator. |
| core-service/src/test/groovy/javasabr/mqtt/service/impl/TlsMqttConnectionFactoryTest.groovy | Adds test for TLS factory allocator sharing. |
| core-service/src/main/java/javasabr/mqtt/service/impl/TlsMqttConnectionFactory.java | Adds TLS connection factory wiring SSLContext + TLS props. |
| core-service/src/main/java/javasabr/mqtt/service/impl/PlainMqttConnectionFactory.java | Renames/updates plain connection factory to pass MqttPacketCreator. |
| buildSrc/src/test/resources/log4j2-test.xml | Adds buildSrc test Log4j2 config. |
| buildSrc/src/main/groovy/configure-java.gradle | Adds logging deps to convention and adjusts test runtime classpath. |
| build.gradle | Centralizes excludes and adds forced SLF4J resolution strategy. |
| application/src/test/resources/test-acl.gacl | Extends test ACL rules for TLS client IDs/topics. |
| application/src/test/groovy/javasabr/mqtt/broker/application/TlsIntegrationSpecification.groovy | Adds TLS client builders and TLS Spring test configuration. |
| application/src/test/groovy/javasabr/mqtt/broker/application/TlsCommunicationTest.groovy | Adds TLS connect/publish tests for MQTT 3.1.1 and MQTT 5. |
| application/src/test/groovy/javasabr/mqtt/broker/application/TestSslPropertiesInitializer.groovy | Injects generated keystore/truststore paths into Spring test env. |
| application/src/test/groovy/javasabr/mqtt/broker/application/IntegrationSpecification.groovy | Switches test config to plain-network test config. |
| application/src/test/groovy/javasabr/mqtt/broker/application/config/TlsNetworkTestConfig.groovy | Adds Spring test config to start TLS network on an ephemeral port. |
| application/src/test/groovy/javasabr/mqtt/broker/application/config/PlainNetworkTestConfig.groovy | Adds Spring test config to start plain network on an ephemeral port. |
| application/src/test/groovy/javasabr/mqtt/broker/application/config/MqttTlsSpringConfigTest.groovy | Adds unit test for TLS property mapping. |
| application/src/test/groovy/javasabr/mqtt/broker/application/config/MqttBrokerTestConfig.groovy | Removes older test config that probed for random ports. |
| application/src/main/java/javasabr/mqtt/broker/application/config/MqttTlsSpringConfig.java | Adds Spring beans for TLS properties, SSLContext, TLS network + starter. |
| application/src/main/java/javasabr/mqtt/broker/application/config/MqttBrokerSpringConfig.java | Wires MqttPacketCreator, plain connection factory, and imports TLS config. |
| application/build.gradle | Removes explicit logging deps (moved to convention). |
Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com>
| @Value("${mqtt.external.tls.truststore-path:}") String truststorePath, | ||
| @Value("${mqtt.external.tls.truststore-password:}") String truststorePassword, | ||
| @Value("${mqtt.external.tls.truststore-type:PKCS12}") String truststoreType, | ||
| @Value("${mqtt.external.tls.require-client-cert:true}") boolean requireClientCert, |
There was a problem hiding this comment.
I think 'require-client-cert' should not be true by default, because this connection can be used just to have encrypted traffic
There was a problem hiding this comment.
Zero Trust is a preferable strategy in terms of private network. Disabling client certificate validation is appropriate only for public network. If the developer still wants to trust all clients indiscriminately, he can always disable this check using the property
| MqttPacketCodec mqttPacketCodec) { | ||
| this.sslEngine = sslContext.createSSLEngine(); | ||
| super(network, channel, bufferAllocator, maxPacketsByRead, serverConnectionConfig, mqttUserFactory, mqttPacketCodec); | ||
| this.sslEngine.setUseClientMode(clientMode); | ||
| this.sslEngine.setNeedClientAuth(tlsProperties.requireClientCert()); |
There was a problem hiding this comment.
It's a new Java 25 feature, so the comment is not relevant
| Files.list(tempDir).forEach { Files.deleteIfExists(it) } | ||
| Files.deleteIfExists(tempDir) |
There was a problem hiding this comment.
Stream inherit nor Closable neither AutoClosable, so the comment is not relevant
| super(network, channel, bufferAllocator, maxPacketsByRead); | ||
| this.serverConnectionConfig = serverConnectionConfig; | ||
| this.packetReader = createPacketReader(); | ||
| this.packetWriter = createPacketWriter(); | ||
| this.packetReader = createPacketReader(mqttPacketCodec); | ||
| this.packetWriter = createPacketWriter(mqttPacketCodec); | ||
| this.user = mqttUserFactory.createNetworkUser(this); |
Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com>
Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com>
Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com>
Issue
#34
Description
This pull request adds comprehensive support for Transport Layer Security (TLS) to the MQTT broker, enabling secure client-server communication. The implementation covers the entire stack, from network-level SSL/TLS handling to broker-side configuration and integration testing.
Changes
MqttSslConnectionand associated readers/writers for SSL handling.TlsPropertiesfor flexible SSL configuration.MqttPacketCreatorto decouple logic fromPlainMqttMessageReaderandSslMqttMessageReader.MqttSslConnectionFactoryto manage secure connections.MqttTlsSpringConfigto enable and configure TLS support within the Spring context.TlsCommunicationTest,TlsIntegrationSpecification) to verify secure end-to-end communication.Notes:
MqttPacketCreatorimproves code maintainability and allows cleaner reuse of message creation logic across different transport types.