From 74f538dd629c83ac846b9d2b97f3d11c421c2186 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Arnaud=20Cogolu=C3=A8gnes?= <514737+acogoluegnes@users.noreply.github.com> Date: Wed, 30 Jul 2025 16:44:50 +0200 Subject: [PATCH] Add Netty-based frame handler This commit adds a Netty-based frame handler. All network IO are based on Netty when this frame handler is in use. The client library can benefit of all the flexibility and advantages of Netty: simple API, pluggable IO layer (Java NIO by default, or e.g. native Epoll on Linux). The Netty frame handler deprecates the internal one using Java NIO. The blocking IO frame handler is still the default one in 5.x. The Netty frame handler should be the only one in 6.x. Fixes #1664 --- .github/workflows/test-rabbitmq-alphas.yml | 6 +- .../test-supported-java-versions-main.yml | 6 +- .github/workflows/test.yml | 7 +- pom.xml | 59 +- .../rabbitmq/client/ConnectionFactory.java | 3324 +++++++++-------- .../client/SocketChannelConfigurator.java | 5 + .../client/SocketChannelConfigurators.java | 2 + .../client/SslEngineConfigurator.java | 5 + .../client/SslEngineConfigurators.java | 2 + .../rabbitmq/client/impl/AMQConnection.java | 16 +- .../client/impl/DefaultHeartbeatSender.java | 147 + .../java/com/rabbitmq/client/impl/Frame.java | 30 +- .../rabbitmq/client/impl/FrameHandler.java | 9 + .../rabbitmq/client/impl/HeartbeatSender.java | 151 +- .../client/impl/NettyFrameHandlerFactory.java | 532 +++ .../java/com/rabbitmq/client/impl/Utils.java | 45 +- .../rabbitmq/client/impl/nio/NioContext.java | 2 + .../rabbitmq/client/impl/nio/NioParams.java | 4 + .../rabbitmq/client/impl/nio/NioQueue.java | 2 + .../client/AmqpClientTestExtension.java | 119 +- .../AMQConnectionRefreshCredentialsTest.java | 5 +- .../client/test/BlockedConnectionTest.java | 13 +- .../rabbitmq/client/test/BrokerTestCase.java | 2 +- .../rabbitmq/client/test/ClientTestSuite.java | 4 +- .../com/rabbitmq/client/test/FrameTest.java | 9 +- .../com/rabbitmq/client/test/NettyTest.java | 143 + ...NoAutoRecoveryWhenTcpWindowIsFullTest.java | 2 +- .../client/test/ProtocolVersionMismatch.java | 92 + .../com/rabbitmq/client/test/TestUtils.java | 980 ++--- .../client/test/functional/FrameMax.java | 86 +- .../test/functional/FunctionalTestSuite.java | 112 +- .../client/test/functional/Heartbeat.java | 71 +- .../test/functional/UnexpectedFrames.java | 6 +- .../test/ssl/BadVerifiedConnection.java | 2 + .../client/test/ssl/HostnameVerification.java | 19 +- .../test/{ => ssl}/SslContextFactoryTest.java | 44 +- .../client/test/ssl/SslTestSuite.java | 2 - .../client/test/ssl/TlsConnectionLogging.java | 43 +- .../client/test/ssl/TlsTestUtils.java | 45 + .../client/test/ssl/UnverifiedConnection.java | 3 + .../client/test/ssl/VerifiedConnection.java | 54 +- src/test/resources/logback-test.xml | 3 +- 42 files changed, 3755 insertions(+), 2458 deletions(-) create mode 100644 src/main/java/com/rabbitmq/client/impl/DefaultHeartbeatSender.java create mode 100644 src/main/java/com/rabbitmq/client/impl/NettyFrameHandlerFactory.java create mode 100644 src/test/java/com/rabbitmq/client/test/NettyTest.java create mode 100644 src/test/java/com/rabbitmq/client/test/ProtocolVersionMismatch.java rename src/test/java/com/rabbitmq/client/test/{ => ssl}/SslContextFactoryTest.java (74%) diff --git a/.github/workflows/test-rabbitmq-alphas.yml b/.github/workflows/test-rabbitmq-alphas.yml index 6fe31dfcb7..700e3e32b8 100644 --- a/.github/workflows/test-rabbitmq-alphas.yml +++ b/.github/workflows/test-rabbitmq-alphas.yml @@ -43,9 +43,9 @@ jobs: RABBITMQ_IMAGE: ${{ matrix.rabbitmq-image }} - name: Get dependencies run: make deps - - name: Test with NIO + - name: Test with Netty run: | - ./mvnw verify -P use-nio -Drabbitmqctl.bin=DOCKER:rabbitmq0 \ + ./mvnw verify -Dio.layer=netty -Drabbitmqctl.bin=DOCKER:rabbitmq0 \ -Dtest-broker.A.nodename=rabbit@node0 -Dtest-broker.B.nodename=rabbit@node1 \ -Dca.certificate=./tls-gen/basic/result/ca_certificate.pem \ -Dclient.certificate=./tls-gen/basic/result/client_$(hostname)_certificate.pem \ @@ -53,7 +53,7 @@ jobs: --no-transfer-progress - name: Test with blocking IO run: | - ./mvnw verify -Drabbitmqctl.bin=DOCKER:rabbitmq0 \ + ./mvnw verify -Dio.layer=socket -Drabbitmqctl.bin=DOCKER:rabbitmq0 \ -Dtest-broker.A.nodename=rabbit@node0 -Dtest-broker.B.nodename=rabbit@node1 \ -Dca.certificate=./tls-gen/basic/result/ca_certificate.pem \ -Dclient.certificate=./tls-gen/basic/result/client_$(hostname)_certificate.pem \ diff --git a/.github/workflows/test-supported-java-versions-main.yml b/.github/workflows/test-supported-java-versions-main.yml index 8acb19cb30..6375118d92 100644 --- a/.github/workflows/test-supported-java-versions-main.yml +++ b/.github/workflows/test-supported-java-versions-main.yml @@ -39,9 +39,9 @@ jobs: run: make deps - name: Show version run: ./mvnw --version - - name: Test with NIO + - name: Test with Netty run: | - ./mvnw verify -P use-nio -Drabbitmqctl.bin=DOCKER:rabbitmq \ + ./mvnw verify -Dio.layer=netty -Drabbitmqctl.bin=DOCKER:rabbitmq \ -Dtest-broker.A.nodename=rabbit@$(hostname) -Dmaven.javadoc.skip=true \ -Dca.certificate=./tls-gen/basic/result/ca_certificate.pem \ -Dclient.certificate=./tls-gen/basic/result/client_$(hostname)_certificate.pem \ @@ -50,7 +50,7 @@ jobs: -Dnet.bytebuddy.experimental=true - name: Test with blocking IO run: | - ./mvnw verify -Drabbitmqctl.bin=DOCKER:rabbitmq \ + ./mvnw verify -Dio.layer=socket -Drabbitmqctl.bin=DOCKER:rabbitmq \ -Dtest-broker.A.nodename=rabbit@$(hostname) -Dmaven.javadoc.skip=true \ -Dca.certificate=./tls-gen/basic/result/ca_certificate.pem \ -Dclient.certificate=./tls-gen/basic/result/client_$(hostname)_certificate.pem \ diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index 512b5f2054..6a93eb453a 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -39,9 +39,9 @@ jobs: run: ci/start-cluster.sh - name: Get dependencies run: make deps - - name: Test with NIO + - name: Test with Netty run: | - ./mvnw verify -P use-nio -Drabbitmqctl.bin=DOCKER:rabbitmq0 \ + ./mvnw verify -Dio.layer=netty -Drabbitmqctl.bin=DOCKER:rabbitmq0 \ -Dtest-broker.A.nodename=rabbit@node0 -Dtest-broker.B.nodename=rabbit@node1 \ -Dca.certificate=./tls-gen/basic/result/ca_certificate.pem \ -Dclient.certificate=./tls-gen/basic/result/client_$(hostname)_certificate.pem \ @@ -49,12 +49,11 @@ jobs: --no-transfer-progress - name: Test with blocking IO run: | - ./mvnw verify -Drabbitmqctl.bin=DOCKER:rabbitmq0 \ + ./mvnw verify -Dio.layer=socket -Drabbitmqctl.bin=DOCKER:rabbitmq0 \ -Dtest-broker.A.nodename=rabbit@node0 -Dtest-broker.B.nodename=rabbit@node1 \ -Dca.certificate=./tls-gen/basic/result/ca_certificate.pem \ -Dclient.certificate=./tls-gen/basic/result/client_$(hostname)_certificate.pem \ -Dmaven.javadoc.skip=true \ - -Dtest-client-cert.password= -Dtest-tls-certs.dir=rabbitmq-configuration/tls \ --no-transfer-progress - name: Stop cluster run: docker compose --file ci/cluster/docker-compose.yml down diff --git a/pom.xml b/pom.xml index a893add022..5f9cb96901 100644 --- a/pom.xml +++ b/pom.xml @@ -56,6 +56,7 @@ true 1.7.36 + 4.2.3.Final 4.2.33 1.15.2 1.52.0 @@ -245,30 +246,6 @@ - - - use-nio - - - - org.apache.maven.plugins - maven-failsafe-plugin - ${maven.failsafe.plugin.version} - - - true - true - - ${test-arguments} - - - - - -