From 5eecda8bde9bef29f99e7b71e6a4d9e8d9e2dfd7 Mon Sep 17 00:00:00 2001 From: pivotal-rabbitmq-ci Date: Mon, 5 Jul 2021 14:39:52 +0000 Subject: [PATCH 001/151] [maven-release-plugin] prepare release v5.13.0.RC2 --- pom.xml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/pom.xml b/pom.xml index f9c92a513d..f80f9aae72 100644 --- a/pom.xml +++ b/pom.xml @@ -4,7 +4,7 @@ com.rabbitmq amqp-client - 5.13.0-SNAPSHOT + 5.13.0.RC2 jar RabbitMQ Java Client @@ -42,7 +42,7 @@ https://github.com/rabbitmq/rabbitmq-java-client scm:git:git://github.com/rabbitmq/rabbitmq-java-client.git scm:git:git@github.com:rabbitmq/rabbitmq-java-client.git - HEAD + v5.13.0.RC2 From 790a5fe8dfc13172fe9f0530dce915ef5c8e8357 Mon Sep 17 00:00:00 2001 From: pivotal-rabbitmq-ci Date: Mon, 5 Jul 2021 14:39:57 +0000 Subject: [PATCH 002/151] [maven-release-plugin] prepare for next development iteration --- pom.xml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/pom.xml b/pom.xml index f80f9aae72..f9c92a513d 100644 --- a/pom.xml +++ b/pom.xml @@ -4,7 +4,7 @@ com.rabbitmq amqp-client - 5.13.0.RC2 + 5.13.0-SNAPSHOT jar RabbitMQ Java Client @@ -42,7 +42,7 @@ https://github.com/rabbitmq/rabbitmq-java-client scm:git:git://github.com/rabbitmq/rabbitmq-java-client.git scm:git:git@github.com:rabbitmq/rabbitmq-java-client.git - v5.13.0.RC2 + HEAD From f5828f7b2fc70c35c89a6506ab935d9130fc71f4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Arnaud=20Cogolu=C3=A8gnes?= Date: Mon, 5 Jul 2021 16:42:07 +0200 Subject: [PATCH 003/151] Set release version to 5.13.0.RC3 --- release-versions.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/release-versions.txt b/release-versions.txt index b350937ea3..b68df111be 100644 --- a/release-versions.txt +++ b/release-versions.txt @@ -1,3 +1,3 @@ -RELEASE_VERSION="5.13.0.RC2" +RELEASE_VERSION="5.13.0.RC3" DEVELOPMENT_VERSION="5.13.0-SNAPSHOT" RELEASE_BRANCH="5.x.x-stable" From d46ff7db9291bd8f0be1498187f02892c7ac06ec Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Arnaud=20Cogolu=C3=A8gnes?= Date: Mon, 12 Jul 2021 14:23:42 +0200 Subject: [PATCH 004/151] Set release version to 5.13.0 --- release-versions.txt | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/release-versions.txt b/release-versions.txt index b68df111be..717cff2f97 100644 --- a/release-versions.txt +++ b/release-versions.txt @@ -1,3 +1,3 @@ -RELEASE_VERSION="5.13.0.RC3" -DEVELOPMENT_VERSION="5.13.0-SNAPSHOT" +RELEASE_VERSION="5.13.0" +DEVELOPMENT_VERSION="5.14.0-SNAPSHOT" RELEASE_BRANCH="5.x.x-stable" From 62c993f4af13e0cb7904e66695e333bd2433d1f2 Mon Sep 17 00:00:00 2001 From: pivotal-rabbitmq-ci Date: Mon, 12 Jul 2021 12:34:06 +0000 Subject: [PATCH 005/151] [maven-release-plugin] prepare release v5.13.0 --- pom.xml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/pom.xml b/pom.xml index f9c92a513d..f00ac47285 100644 --- a/pom.xml +++ b/pom.xml @@ -4,7 +4,7 @@ com.rabbitmq amqp-client - 5.13.0-SNAPSHOT + 5.13.0 jar RabbitMQ Java Client @@ -42,7 +42,7 @@ https://github.com/rabbitmq/rabbitmq-java-client scm:git:git://github.com/rabbitmq/rabbitmq-java-client.git scm:git:git@github.com:rabbitmq/rabbitmq-java-client.git - HEAD + v5.13.0 From 51b5abe1e1cd586576eedccdfa21176976167487 Mon Sep 17 00:00:00 2001 From: pivotal-rabbitmq-ci Date: Mon, 12 Jul 2021 12:34:11 +0000 Subject: [PATCH 006/151] [maven-release-plugin] prepare for next development iteration --- pom.xml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/pom.xml b/pom.xml index f00ac47285..10cde42178 100644 --- a/pom.xml +++ b/pom.xml @@ -4,7 +4,7 @@ com.rabbitmq amqp-client - 5.13.0 + 5.14.0-SNAPSHOT jar RabbitMQ Java Client @@ -42,7 +42,7 @@ https://github.com/rabbitmq/rabbitmq-java-client scm:git:git://github.com/rabbitmq/rabbitmq-java-client.git scm:git:git@github.com:rabbitmq/rabbitmq-java-client.git - v5.13.0 + HEAD From c26edc05a01d4550c725ee2a20df8e55b5f1cb55 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Arnaud=20Cogolu=C3=A8gnes?= Date: Mon, 12 Jul 2021 14:47:27 +0200 Subject: [PATCH 007/151] Set release version to 5.14.0.RC1 --- release-versions.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/release-versions.txt b/release-versions.txt index 717cff2f97..19d9bee27b 100644 --- a/release-versions.txt +++ b/release-versions.txt @@ -1,3 +1,3 @@ -RELEASE_VERSION="5.13.0" +RELEASE_VERSION="5.14.0.RC1" DEVELOPMENT_VERSION="5.14.0-SNAPSHOT" RELEASE_BRANCH="5.x.x-stable" From 9131c7811c11408cc5493d1773e0d86f15faae04 Mon Sep 17 00:00:00 2001 From: madun Date: Tue, 6 Jul 2021 20:34:12 +0800 Subject: [PATCH 008/151] =?UTF-8?q?style:=201=E3=80=81format=20two=20line?= =?UTF-8?q?=20align=202=E3=80=81add=20channelMax=20<=200=20condition,=20fr?= =?UTF-8?q?iendly=20tips?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit (cherry picked from commit c80afcfb2f88fa6989ca2c3470fe1af62acbb938) --- .../java/com/rabbitmq/client/impl/ChannelManager.java | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/src/main/java/com/rabbitmq/client/impl/ChannelManager.java b/src/main/java/com/rabbitmq/client/impl/ChannelManager.java index 59f7bb3fee..0264adeb92 100644 --- a/src/main/java/com/rabbitmq/client/impl/ChannelManager.java +++ b/src/main/java/com/rabbitmq/client/impl/ChannelManager.java @@ -39,9 +39,9 @@ public class ChannelManager { /** Monitor for _channelMap and channelNumberAllocator */ private final Object monitor = new Object(); - /** Mapping from 1.._channelMax to {@link ChannelN} instance */ - private final Map _channelMap = new HashMap(); - private final IntAllocator channelNumberAllocator; + /** Mapping from 1.._channelMax to {@link ChannelN} instance */ + private final Map _channelMap = new HashMap(); + private final IntAllocator channelNumberAllocator; private final ConsumerWorkService workService; @@ -70,6 +70,8 @@ public ChannelManager(ConsumerWorkService workService, int channelMax, ThreadFac public ChannelManager(ConsumerWorkService workService, int channelMax, ThreadFactory threadFactory, MetricsCollector metricsCollector) { + if (channelMax < 0) + throw new IllegalStateException("create ChannelManager: 'channelMax' must be greater or equal to 0."); if (channelMax == 0) { // The framing encoding only allows for unsigned 16-bit integers // for the channel number From f52324aa06d64bc7ceed640724f268703a6c760e Mon Sep 17 00:00:00 2001 From: madun Date: Thu, 8 Jul 2021 09:15:21 +0800 Subject: [PATCH 009/151] =?UTF-8?q?style:=201=E3=80=81modify=20IllegalStat?= =?UTF-8?q?eException=20to=20IllegalArgumentException?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit (cherry picked from commit 0a4f08bddf61efbe0625d95e03eedf00b17d6b39) --- src/main/java/com/rabbitmq/client/impl/ChannelManager.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main/java/com/rabbitmq/client/impl/ChannelManager.java b/src/main/java/com/rabbitmq/client/impl/ChannelManager.java index 0264adeb92..fb0490eade 100644 --- a/src/main/java/com/rabbitmq/client/impl/ChannelManager.java +++ b/src/main/java/com/rabbitmq/client/impl/ChannelManager.java @@ -71,7 +71,7 @@ public ChannelManager(ConsumerWorkService workService, int channelMax, ThreadFac public ChannelManager(ConsumerWorkService workService, int channelMax, ThreadFactory threadFactory, MetricsCollector metricsCollector) { if (channelMax < 0) - throw new IllegalStateException("create ChannelManager: 'channelMax' must be greater or equal to 0."); + throw new IllegalArgumentException("create ChannelManager: 'channelMax' must be greater or equal to 0."); if (channelMax == 0) { // The framing encoding only allows for unsigned 16-bit integers // for the channel number From 5b6e4d3435fb27774a73ed7b16a90add5f1e355f Mon Sep 17 00:00:00 2001 From: madun Date: Fri, 9 Jul 2021 16:47:42 +0800 Subject: [PATCH 010/151] =?UTF-8?q?refactor:=201=E3=80=81optimize=20class?= =?UTF-8?q?=20code=20structure?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit (cherry picked from commit 430412d3c6439d4745adf1ae5617153ccaaf7d73) --- .../com/rabbitmq/client/impl/recovery/RecordedEntity.java | 2 +- .../com/rabbitmq/client/impl/recovery/RecordedExchange.java | 1 + .../rabbitmq/client/impl/recovery/RecordedNamedEntity.java | 5 ++++- .../com/rabbitmq/client/impl/recovery/RecordedQueue.java | 5 +++-- .../rabbitmq/client/impl/recovery/RecordedQueueBinding.java | 2 +- 5 files changed, 10 insertions(+), 5 deletions(-) diff --git a/src/main/java/com/rabbitmq/client/impl/recovery/RecordedEntity.java b/src/main/java/com/rabbitmq/client/impl/recovery/RecordedEntity.java index a9fae4c3ae..a56f58b88a 100644 --- a/src/main/java/com/rabbitmq/client/impl/recovery/RecordedEntity.java +++ b/src/main/java/com/rabbitmq/client/impl/recovery/RecordedEntity.java @@ -20,7 +20,7 @@ /** * @since 3.3.0 */ -public class RecordedEntity { +public abstract class RecordedEntity { protected final AutorecoveringChannel channel; public RecordedEntity(AutorecoveringChannel channel) { diff --git a/src/main/java/com/rabbitmq/client/impl/recovery/RecordedExchange.java b/src/main/java/com/rabbitmq/client/impl/recovery/RecordedExchange.java index 7625b5a870..aaedcbbf58 100644 --- a/src/main/java/com/rabbitmq/client/impl/recovery/RecordedExchange.java +++ b/src/main/java/com/rabbitmq/client/impl/recovery/RecordedExchange.java @@ -31,6 +31,7 @@ public RecordedExchange(AutorecoveringChannel channel, String name) { super(channel, name); } + @Override public void recover() throws IOException { this.channel.getDelegate().exchangeDeclare(this.name, this.type, this.durable, this.autoDelete, this.arguments); } diff --git a/src/main/java/com/rabbitmq/client/impl/recovery/RecordedNamedEntity.java b/src/main/java/com/rabbitmq/client/impl/recovery/RecordedNamedEntity.java index 6ea8b6fa96..7b5a86a8f9 100644 --- a/src/main/java/com/rabbitmq/client/impl/recovery/RecordedNamedEntity.java +++ b/src/main/java/com/rabbitmq/client/impl/recovery/RecordedNamedEntity.java @@ -15,10 +15,11 @@ package com.rabbitmq.client.impl.recovery; +import java.io.IOException; /** * @since 3.3.0 */ -public class RecordedNamedEntity extends RecordedEntity { +public abstract class RecordedNamedEntity extends RecordedEntity { protected String name; public RecordedNamedEntity(AutorecoveringChannel channel, String name) { @@ -26,6 +27,8 @@ public RecordedNamedEntity(AutorecoveringChannel channel, String name) { this.name = name; } + public abstract void recover() throws IOException; + public String getName() { return name; } diff --git a/src/main/java/com/rabbitmq/client/impl/recovery/RecordedQueue.java b/src/main/java/com/rabbitmq/client/impl/recovery/RecordedQueue.java index 52caced2af..b41ecdc302 100644 --- a/src/main/java/com/rabbitmq/client/impl/recovery/RecordedQueue.java +++ b/src/main/java/com/rabbitmq/client/impl/recovery/RecordedQueue.java @@ -55,6 +55,7 @@ public boolean isServerNamed() { return this.serverNamed; } + @Override public void recover() throws IOException { this.name = this.channel.getDelegate().queueDeclare(this.getNameToUseForRecovery(), this.durable, @@ -71,7 +72,7 @@ public RecordedQueue durable(boolean value) { this.durable = value; return this; } - + public boolean isDurable() { return this.durable; } @@ -80,7 +81,7 @@ public RecordedQueue autoDelete(boolean value) { this.autoDelete = value; return this; } - + public boolean isAutoDelete() { return this.autoDelete; } diff --git a/src/main/java/com/rabbitmq/client/impl/recovery/RecordedQueueBinding.java b/src/main/java/com/rabbitmq/client/impl/recovery/RecordedQueueBinding.java index 12ed3d48bb..37bbb14fe5 100644 --- a/src/main/java/com/rabbitmq/client/impl/recovery/RecordedQueueBinding.java +++ b/src/main/java/com/rabbitmq/client/impl/recovery/RecordedQueueBinding.java @@ -27,7 +27,7 @@ public RecordedQueueBinding(AutorecoveringChannel channel) { @Override public void recover() throws IOException { - this.channel.getDelegate().queueBind(this.getDestination(), this.getSource(), this.routingKey, this.arguments); + this.channel.getDelegate().queueBind(this.destination, this.source, this.routingKey, this.arguments); } @Override From 267c3553475f5284ec5ead6c34ae27893d3e819f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Arnaud=20Cogolu=C3=A8gnes?= Date: Mon, 26 Jul 2021 14:17:20 +0200 Subject: [PATCH 011/151] Disable global QoS temporarily Because of a regression in 3.9.x. References rabbitmq/rabbitmq-server#3230 (cherry picked from commit 559c4cb3e9803b2144e7900c13d26a0250da66cf) --- .../com/rabbitmq/client/test/functional/QosTests.java | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/src/test/java/com/rabbitmq/client/test/functional/QosTests.java b/src/test/java/com/rabbitmq/client/test/functional/QosTests.java index 276a363f4e..b347382f0d 100644 --- a/src/test/java/com/rabbitmq/client/test/functional/QosTests.java +++ b/src/test/java/com/rabbitmq/client/test/functional/QosTests.java @@ -31,6 +31,7 @@ import java.util.Map; import java.util.concurrent.TimeoutException; +import org.junit.Ignore; import org.junit.Test; import com.rabbitmq.client.AMQP; @@ -119,6 +120,7 @@ public static List drain(QueueingConsumer c, int n) drain(c, 2); } + @Ignore @Test public void noAckObeysLimit() throws IOException { @@ -142,6 +144,7 @@ public static List drain(QueueingConsumer c, int n) drain(c2, 1); } + @Ignore @Test public void permutations() throws IOException { @@ -159,6 +162,7 @@ public static List drain(QueueingConsumer c, int n) } } + @Ignore @Test public void fairness() throws IOException { @@ -188,6 +192,7 @@ public static List drain(QueueingConsumer c, int n) } + @Ignore @Test public void singleChannelAndQueueFairness() throws IOException { @@ -237,6 +242,7 @@ public static List drain(QueueingConsumer c, int n) assertTrue(counts.get("c2").intValue() > 0); } + @Ignore @Test public void consumerLifecycle() throws IOException { @@ -258,6 +264,7 @@ public static List drain(QueueingConsumer c, int n) channel.queueDelete(queue); } + @Ignore @Test public void setLimitAfterConsume() throws IOException { @@ -282,6 +289,7 @@ public static List drain(QueueingConsumer c, int n) drain(c, 1); } + @Ignore @Test public void limitDecrease() throws IOException { @@ -302,6 +310,7 @@ public static List drain(QueueingConsumer c, int n) drain(c, 2); } + @Ignore @Test public void limitingMultipleChannels() throws IOException { @@ -338,6 +347,7 @@ public static List drain(QueueingConsumer c, int n) drain(c, 1); } + @Ignore @Test public void recoverReducesLimit() throws Exception { channel.basicQos(2, true); QueueingConsumer c = new QueueingConsumer(channel); From 73454cdbedc60b25788c4f61166b3859105afad5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Arnaud=20Cogolu=C3=A8gnes?= Date: Wed, 28 Jul 2021 09:46:16 +0200 Subject: [PATCH 012/151] Bump dependencies References #699 (cherry picked from commit 5653e1cac355fee3cc6c8e1ce3bc82197b5ab7cb) --- pom.xml | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/pom.xml b/pom.xml index 10cde42178..b04e0943d1 100644 --- a/pom.xml +++ b/pom.xml @@ -54,10 +54,10 @@ UTF-8 UTF-8 - 1.7.31 - 4.2.2 - 1.7.1 - 2.12.3 + 1.7.32 + 4.2.3 + 1.7.2 + 2.12.4 1.2.3 4.13.2 3.11.2 From 1e5e40273e3e0fb43d44981a7a952b9f564c1046 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Arnaud=20Cogolu=C3=A8gnes?= Date: Wed, 28 Jul 2021 09:46:56 +0200 Subject: [PATCH 013/151] Bump test dependencies (cherry picked from commit 281b679d3f076b9d2adbb8c8eeb983958eb1e3f4) --- pom.xml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/pom.xml b/pom.xml index b04e0943d1..c290b479c3 100644 --- a/pom.xml +++ b/pom.xml @@ -58,11 +58,11 @@ 4.2.3 1.7.2 2.12.4 - 1.2.3 + 1.2.5 4.13.2 3.11.2 3.20.2 - 9.4.42.v20210604 + 9.4.43.v20210629 1.69 3.2.0 From 326e142eb6e89d4c0e5b94322d2aed81e4357659 Mon Sep 17 00:00:00 2001 From: yandryakov Date: Thu, 29 Jul 2021 16:07:02 +0300 Subject: [PATCH 014/151] support underflow handling without thread sleep (cherry picked from commit ba696986acad8aaee7365aa56e90ccef08bce4bc) --- .../nio/SocketChannelFrameHandlerState.java | 24 ++++++++++++++--- .../impl/nio/SslEngineFrameBuilder.java | 27 ++++++++++++------- 2 files changed, 37 insertions(+), 14 deletions(-) diff --git a/src/main/java/com/rabbitmq/client/impl/nio/SocketChannelFrameHandlerState.java b/src/main/java/com/rabbitmq/client/impl/nio/SocketChannelFrameHandlerState.java index 50f08a59f2..87c1d08928 100644 --- a/src/main/java/com/rabbitmq/client/impl/nio/SocketChannelFrameHandlerState.java +++ b/src/main/java/com/rabbitmq/client/impl/nio/SocketChannelFrameHandlerState.java @@ -26,6 +26,8 @@ import java.nio.ByteBuffer; import java.nio.channels.SelectionKey; import java.nio.channels.SocketChannel; +import java.util.concurrent.atomic.AtomicBoolean; + /** * @@ -70,6 +72,8 @@ public class SocketChannelFrameHandlerState { final FrameBuilder frameBuilder; + private final AtomicBoolean isUnderflowHandlingEnabled = new AtomicBoolean(false); + public SocketChannelFrameHandlerState(SocketChannel channel, NioLoopContext nioLoopsState, NioParams nioParams, SSLEngine sslEngine) { this.channel = channel; this.readSelectorState = nioLoopsState.readSelectorState; @@ -105,7 +109,7 @@ public SocketChannelFrameHandlerState(SocketChannel channel, NioLoopContext nioL this.outputStream = new DataOutputStream( new SslEngineByteBufferOutputStream(sslEngine, plainOut, cipherOut, channel) ); - this.frameBuilder = new SslEngineFrameBuilder(sslEngine, plainIn, cipherIn, channel); + this.frameBuilder = new SslEngineFrameBuilder(sslEngine, plainIn, cipherIn, channel, isUnderflowHandlingEnabled); } } @@ -176,11 +180,14 @@ void endWriteSequence() { void prepareForReadSequence() throws IOException { if(ssl) { - cipherIn.clear(); - plainIn.clear(); + if (!isUnderflowHandlingEnabled.get()) { + cipherIn.clear(); + cipherIn.flip(); + } - cipherIn.flip(); + plainIn.clear(); plainIn.flip(); + } else { NioHelper.read(channel, plainIn); plainIn.flip(); @@ -189,6 +196,15 @@ void prepareForReadSequence() throws IOException { boolean continueReading() throws IOException { if(ssl) { + if (isUnderflowHandlingEnabled.get()) { + int bytesRead = NioHelper.read(channel, cipherIn); + if (bytesRead == 0) { + return false; + } else { + cipherIn.flip(); + return true; + } + } if (!plainIn.hasRemaining() && !cipherIn.hasRemaining()) { // need to try to read something cipherIn.clear(); diff --git a/src/main/java/com/rabbitmq/client/impl/nio/SslEngineFrameBuilder.java b/src/main/java/com/rabbitmq/client/impl/nio/SslEngineFrameBuilder.java index c2f1923874..34295fb36a 100644 --- a/src/main/java/com/rabbitmq/client/impl/nio/SslEngineFrameBuilder.java +++ b/src/main/java/com/rabbitmq/client/impl/nio/SslEngineFrameBuilder.java @@ -21,6 +21,8 @@ import java.io.IOException; import java.nio.ByteBuffer; import java.nio.channels.ReadableByteChannel; +import java.util.concurrent.atomic.AtomicBoolean; + /** * Sub-class of {@link FrameBuilder} that unwraps crypted data from the network. @@ -32,20 +34,25 @@ public class SslEngineFrameBuilder extends FrameBuilder { private final ByteBuffer cipherBuffer; - public SslEngineFrameBuilder(SSLEngine sslEngine, ByteBuffer plainIn, ByteBuffer cipherIn, ReadableByteChannel channel) { + private final AtomicBoolean isUnderflowHandlingEnabled; + + public SslEngineFrameBuilder(SSLEngine sslEngine, ByteBuffer plainIn, ByteBuffer cipherIn, ReadableByteChannel channel, final AtomicBoolean isUnderflowHandlingEnabled) { super(channel, plainIn); this.sslEngine = sslEngine; this.cipherBuffer = cipherIn; + this.isUnderflowHandlingEnabled = isUnderflowHandlingEnabled; } @Override protected boolean somethingToRead() throws IOException { - if (applicationBuffer.hasRemaining()) { + if (applicationBuffer.hasRemaining() && !isUnderflowHandlingEnabled.get()) { return true; } else { applicationBuffer.clear(); - while (true) { + boolean underflowHandling = false; + + try { SSLEngineResult result = sslEngine.unwrap(cipherBuffer, applicationBuffer); switch (result.getStatus()) { case OK: @@ -59,18 +66,18 @@ protected boolean somethingToRead() throws IOException { throw new SSLException("buffer overflow in read"); case BUFFER_UNDERFLOW: cipherBuffer.compact(); - int read = NioHelper.read(channel, cipherBuffer); - if (read == 0) { - return false; - } - cipherBuffer.flip(); - break; + underflowHandling = true; + return false; case CLOSED: throw new SSLException("closed in read"); default: throw new IllegalStateException("Invalid SSL status: " + result.getStatus()); - } + } + } finally { + isUnderflowHandlingEnabled.set(underflowHandling); } + + return false; } } From c3d9e7532d8f2040ee71afc06a5e11c244988dae Mon Sep 17 00:00:00 2001 From: yandryakov Date: Thu, 29 Jul 2021 18:34:47 +0300 Subject: [PATCH 015/151] refactoring - make isUnderflowHandlingEnabled private property (cherry picked from commit 217a5e8c2a8e42748b6a33dadae9443ea7f7119a) --- .../com/rabbitmq/client/impl/nio/FrameBuilder.java | 5 +++++ .../impl/nio/SocketChannelFrameHandlerState.java | 9 +++------ .../client/impl/nio/SslEngineFrameBuilder.java | 14 ++++++++------ 3 files changed, 16 insertions(+), 12 deletions(-) diff --git a/src/main/java/com/rabbitmq/client/impl/nio/FrameBuilder.java b/src/main/java/com/rabbitmq/client/impl/nio/FrameBuilder.java index 8352174360..813e328b9e 100644 --- a/src/main/java/com/rabbitmq/client/impl/nio/FrameBuilder.java +++ b/src/main/java/com/rabbitmq/client/impl/nio/FrameBuilder.java @@ -200,4 +200,9 @@ private void handleProtocolVersionMismatch() throws IOException { } throw x; } + + //Indicates ssl underflow state - means that cipherBuffer should aggregate next chunks of bytes + public boolean isUnderflowHandlingEnabled() { + return false; + } } diff --git a/src/main/java/com/rabbitmq/client/impl/nio/SocketChannelFrameHandlerState.java b/src/main/java/com/rabbitmq/client/impl/nio/SocketChannelFrameHandlerState.java index 87c1d08928..4f1e4dc885 100644 --- a/src/main/java/com/rabbitmq/client/impl/nio/SocketChannelFrameHandlerState.java +++ b/src/main/java/com/rabbitmq/client/impl/nio/SocketChannelFrameHandlerState.java @@ -26,7 +26,6 @@ import java.nio.ByteBuffer; import java.nio.channels.SelectionKey; import java.nio.channels.SocketChannel; -import java.util.concurrent.atomic.AtomicBoolean; /** @@ -72,8 +71,6 @@ public class SocketChannelFrameHandlerState { final FrameBuilder frameBuilder; - private final AtomicBoolean isUnderflowHandlingEnabled = new AtomicBoolean(false); - public SocketChannelFrameHandlerState(SocketChannel channel, NioLoopContext nioLoopsState, NioParams nioParams, SSLEngine sslEngine) { this.channel = channel; this.readSelectorState = nioLoopsState.readSelectorState; @@ -109,7 +106,7 @@ public SocketChannelFrameHandlerState(SocketChannel channel, NioLoopContext nioL this.outputStream = new DataOutputStream( new SslEngineByteBufferOutputStream(sslEngine, plainOut, cipherOut, channel) ); - this.frameBuilder = new SslEngineFrameBuilder(sslEngine, plainIn, cipherIn, channel, isUnderflowHandlingEnabled); + this.frameBuilder = new SslEngineFrameBuilder(sslEngine, plainIn, cipherIn, channel); } } @@ -180,7 +177,7 @@ void endWriteSequence() { void prepareForReadSequence() throws IOException { if(ssl) { - if (!isUnderflowHandlingEnabled.get()) { + if (!frameBuilder.isUnderflowHandlingEnabled()) { cipherIn.clear(); cipherIn.flip(); } @@ -196,7 +193,7 @@ void prepareForReadSequence() throws IOException { boolean continueReading() throws IOException { if(ssl) { - if (isUnderflowHandlingEnabled.get()) { + if (frameBuilder.isUnderflowHandlingEnabled()) { int bytesRead = NioHelper.read(channel, cipherIn); if (bytesRead == 0) { return false; diff --git a/src/main/java/com/rabbitmq/client/impl/nio/SslEngineFrameBuilder.java b/src/main/java/com/rabbitmq/client/impl/nio/SslEngineFrameBuilder.java index 34295fb36a..8b6ecaf8ab 100644 --- a/src/main/java/com/rabbitmq/client/impl/nio/SslEngineFrameBuilder.java +++ b/src/main/java/com/rabbitmq/client/impl/nio/SslEngineFrameBuilder.java @@ -21,7 +21,6 @@ import java.io.IOException; import java.nio.ByteBuffer; import java.nio.channels.ReadableByteChannel; -import java.util.concurrent.atomic.AtomicBoolean; /** @@ -34,18 +33,17 @@ public class SslEngineFrameBuilder extends FrameBuilder { private final ByteBuffer cipherBuffer; - private final AtomicBoolean isUnderflowHandlingEnabled; + private boolean isUnderflowHandlingEnabled = false; - public SslEngineFrameBuilder(SSLEngine sslEngine, ByteBuffer plainIn, ByteBuffer cipherIn, ReadableByteChannel channel, final AtomicBoolean isUnderflowHandlingEnabled) { + public SslEngineFrameBuilder(SSLEngine sslEngine, ByteBuffer plainIn, ByteBuffer cipherIn, ReadableByteChannel channel) { super(channel, plainIn); this.sslEngine = sslEngine; this.cipherBuffer = cipherIn; - this.isUnderflowHandlingEnabled = isUnderflowHandlingEnabled; } @Override protected boolean somethingToRead() throws IOException { - if (applicationBuffer.hasRemaining() && !isUnderflowHandlingEnabled.get()) { + if (applicationBuffer.hasRemaining() && !isUnderflowHandlingEnabled) { return true; } else { applicationBuffer.clear(); @@ -74,11 +72,15 @@ protected boolean somethingToRead() throws IOException { throw new IllegalStateException("Invalid SSL status: " + result.getStatus()); } } finally { - isUnderflowHandlingEnabled.set(underflowHandling); + isUnderflowHandlingEnabled = underflowHandling; } return false; } } + @Override + public boolean isUnderflowHandlingEnabled() { + return isUnderflowHandlingEnabled; + } } From 6d4c9f4b8ab9f8219b4938de8740145526f4a988 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Arnaud=20Cogolu=C3=A8gnes?= Date: Fri, 30 Jul 2021 17:39:41 +0200 Subject: [PATCH 016/151] Re-enable QoS tests Now fix is in master and 3.9.x. (cherry picked from commit 12f9f75bdf973ed74082df5a0fc5d664610c1595) --- .../com/rabbitmq/client/test/functional/QosTests.java | 10 ---------- 1 file changed, 10 deletions(-) diff --git a/src/test/java/com/rabbitmq/client/test/functional/QosTests.java b/src/test/java/com/rabbitmq/client/test/functional/QosTests.java index b347382f0d..276a363f4e 100644 --- a/src/test/java/com/rabbitmq/client/test/functional/QosTests.java +++ b/src/test/java/com/rabbitmq/client/test/functional/QosTests.java @@ -31,7 +31,6 @@ import java.util.Map; import java.util.concurrent.TimeoutException; -import org.junit.Ignore; import org.junit.Test; import com.rabbitmq.client.AMQP; @@ -120,7 +119,6 @@ public static List drain(QueueingConsumer c, int n) drain(c, 2); } - @Ignore @Test public void noAckObeysLimit() throws IOException { @@ -144,7 +142,6 @@ public static List drain(QueueingConsumer c, int n) drain(c2, 1); } - @Ignore @Test public void permutations() throws IOException { @@ -162,7 +159,6 @@ public static List drain(QueueingConsumer c, int n) } } - @Ignore @Test public void fairness() throws IOException { @@ -192,7 +188,6 @@ public static List drain(QueueingConsumer c, int n) } - @Ignore @Test public void singleChannelAndQueueFairness() throws IOException { @@ -242,7 +237,6 @@ public static List drain(QueueingConsumer c, int n) assertTrue(counts.get("c2").intValue() > 0); } - @Ignore @Test public void consumerLifecycle() throws IOException { @@ -264,7 +258,6 @@ public static List drain(QueueingConsumer c, int n) channel.queueDelete(queue); } - @Ignore @Test public void setLimitAfterConsume() throws IOException { @@ -289,7 +282,6 @@ public static List drain(QueueingConsumer c, int n) drain(c, 1); } - @Ignore @Test public void limitDecrease() throws IOException { @@ -310,7 +302,6 @@ public static List drain(QueueingConsumer c, int n) drain(c, 2); } - @Ignore @Test public void limitingMultipleChannels() throws IOException { @@ -347,7 +338,6 @@ public static List drain(QueueingConsumer c, int n) drain(c, 1); } - @Ignore @Test public void recoverReducesLimit() throws Exception { channel.basicQos(2, true); QueueingConsumer c = new QueueingConsumer(channel); From 34ccee73d2e208e997ff69f2a04e7a752a36fce5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Arnaud=20Cogolu=C3=A8gnes?= Date: Mon, 30 Aug 2021 10:51:44 +0200 Subject: [PATCH 017/151] Bump dependencies References #699 (cherry picked from commit 2e098ffa521f29236a9c0ac3152bd534a9081bd2) --- pom.xml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/pom.xml b/pom.xml index c290b479c3..40f2fced6f 100644 --- a/pom.xml +++ b/pom.xml @@ -56,8 +56,8 @@ 1.7.32 4.2.3 - 1.7.2 - 2.12.4 + 1.7.3 + 2.12.5 1.2.5 4.13.2 3.11.2 From 653d08b801c0dae5844709bf5adcf9d15371e320 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Arnaud=20Cogolu=C3=A8gnes?= Date: Mon, 30 Aug 2021 10:52:51 +0200 Subject: [PATCH 018/151] Bump test dependencies (cherry picked from commit 1a11d9fef88e14776554839142b07454903e9a05) --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index 40f2fced6f..9e611a7a91 100644 --- a/pom.xml +++ b/pom.xml @@ -60,7 +60,7 @@ 2.12.5 1.2.5 4.13.2 - 3.11.2 + 3.12.4 3.20.2 9.4.43.v20210629 1.69 From 613927e0bf0da3c6624c7b3b7b799ec19f91545e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Arnaud=20Cogolu=C3=A8gnes?= Date: Tue, 28 Sep 2021 16:53:59 +0200 Subject: [PATCH 019/151] Bump Micrometer to 1.7.4 References #699 (cherry picked from commit c879d7a0404e49242623f101a1e861400602df9b) --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index 9e611a7a91..37174092df 100644 --- a/pom.xml +++ b/pom.xml @@ -56,7 +56,7 @@ 1.7.32 4.2.3 - 1.7.3 + 1.7.4 2.12.5 1.2.5 4.13.2 From a43612fdd83d964165f22cefb6aa250e6f3de4d9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Arnaud=20Cogolu=C3=A8gnes?= Date: Tue, 28 Sep 2021 16:54:54 +0200 Subject: [PATCH 020/151] Bump test dependencies (cherry picked from commit 2da7a4acbf9a80b7e0e00e167a9992713f8bb88d) --- pom.xml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/pom.xml b/pom.xml index 37174092df..09ee9df890 100644 --- a/pom.xml +++ b/pom.xml @@ -58,10 +58,10 @@ 4.2.3 1.7.4 2.12.5 - 1.2.5 + 1.2.6 4.13.2 3.12.4 - 3.20.2 + 3.21.0 9.4.43.v20210629 1.69 From 4fd4ec9ababf5367b97cc0f8ddff9a8af2f50129 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Arnaud=20Cogolu=C3=A8gnes?= Date: Mon, 4 Oct 2021 09:20:51 +0200 Subject: [PATCH 021/151] Bump Maven to 3.8.3 (cherry picked from commit e01c208d21318371e755b91a072f47fb12981de2) --- .mvn/wrapper/maven-wrapper.properties | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.mvn/wrapper/maven-wrapper.properties b/.mvn/wrapper/maven-wrapper.properties index 642d572ce9..a9f1ef87bb 100644 --- a/.mvn/wrapper/maven-wrapper.properties +++ b/.mvn/wrapper/maven-wrapper.properties @@ -1,2 +1,2 @@ -distributionUrl=https://repo.maven.apache.org/maven2/org/apache/maven/apache-maven/3.6.3/apache-maven-3.6.3-bin.zip +distributionUrl=https://repo.maven.apache.org/maven2/org/apache/maven/apache-maven/3.8.3/apache-maven-3.8.3-bin.zip wrapperUrl=https://repo.maven.apache.org/maven2/io/takari/maven-wrapper/0.5.6/maven-wrapper-0.5.6.jar From b123de5143c277b26b3e49904b89e1666dcfa2aa Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Arnaud=20Cogolu=C3=A8gnes?= Date: Tue, 5 Oct 2021 14:45:46 +0200 Subject: [PATCH 022/151] Bump optional dependencies References #699 (cherry picked from commit 54fa481d31a552a05b60791347c973784b4a7ec9) --- pom.xml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/pom.xml b/pom.xml index 09ee9df890..ea211df5c4 100644 --- a/pom.xml +++ b/pom.xml @@ -55,9 +55,9 @@ UTF-8 1.7.32 - 4.2.3 + 4.2.4 1.7.4 - 2.12.5 + 2.13.0 1.2.6 4.13.2 3.12.4 From aa3bf23a3d7de4abe6a5f7176f3009d7264e537c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Arnaud=20Cogolu=C3=A8gnes?= Date: Tue, 5 Oct 2021 14:46:10 +0200 Subject: [PATCH 023/151] Bump test dependency (cherry picked from commit 3e5e2789baf8c9172a48474fdfd712cde9c2128f) --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index ea211df5c4..7959c57ff6 100644 --- a/pom.xml +++ b/pom.xml @@ -62,7 +62,7 @@ 4.13.2 3.12.4 3.21.0 - 9.4.43.v20210629 + 9.4.44.v20210927 1.69 3.2.0 From 7d9565b4158209426299fd1acb63fe5516cc55c3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Arnaud=20Cogolu=C3=A8gnes?= Date: Thu, 21 Oct 2021 09:30:52 +0200 Subject: [PATCH 024/151] Bump Micrometer to 1.7.5 References #699 (cherry picked from commit 4de6eb709330644e7707b3e0a9652b5f09c16c70) --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index 7959c57ff6..de16922b29 100644 --- a/pom.xml +++ b/pom.xml @@ -56,7 +56,7 @@ 1.7.32 4.2.4 - 1.7.4 + 1.7.5 2.13.0 1.2.6 4.13.2 From 2def01691f5593dcb5bf1e119b3c6e4f0bac29c8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Arnaud=20Cogolu=C3=A8gnes?= Date: Thu, 21 Oct 2021 09:31:43 +0200 Subject: [PATCH 025/151] Bump Mockito to 4.0.0 (cherry picked from commit 15068a4d569e67a66cac7534270fe8e97761f741) --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index de16922b29..721405e4a5 100644 --- a/pom.xml +++ b/pom.xml @@ -60,7 +60,7 @@ 2.13.0 1.2.6 4.13.2 - 3.12.4 + 4.0.0 3.21.0 9.4.44.v20210927 1.69 From d3e957f79291d2ff8123a7d942e38501580344ae Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Arnaud=20Cogolu=C3=A8gnes?= Date: Mon, 25 Oct 2021 10:01:04 +0200 Subject: [PATCH 026/151] Fix dead lettering flaky test It was using Thread.sleep() statements, which are not reliable, using polling for assertion instead. (cherry picked from commit ea8aa89fafbb96260a31b63898d93128ed23adea) --- .../com/rabbitmq/client/test/TestUtils.java | 25 +++++++++--- .../test/functional/DeadLetterExchange.java | 39 +++++++++++++++---- 2 files changed, 51 insertions(+), 13 deletions(-) diff --git a/src/test/java/com/rabbitmq/client/test/TestUtils.java b/src/test/java/com/rabbitmq/client/test/TestUtils.java index e16bca6f40..72e0b56cea 100644 --- a/src/test/java/com/rabbitmq/client/test/TestUtils.java +++ b/src/test/java/com/rabbitmq/client/test/TestUtils.java @@ -56,9 +56,20 @@ public static ConnectionFactory connectionFactory() { return connectionFactory; } - public static void waitAtMost(Duration timeout, BooleanSupplier condition) { - if (condition.getAsBoolean()) { - return; + @FunctionalInterface + public interface CallableBooleanSupplier { + + boolean getAsBoolean() throws Exception; + + } + + public static void waitAtMost(Duration timeout, CallableBooleanSupplier condition) { + try { + if (condition.getAsBoolean()) { + return; + } + } catch (Exception e) { + throw new RuntimeException(e); } int waitTime = 100; int waitedTime = 0; @@ -70,8 +81,12 @@ public static void waitAtMost(Duration timeout, BooleanSupplier condition) { Thread.currentThread().interrupt(); throw new RuntimeException(e); } - if (condition.getAsBoolean()) { - return; + try { + if (condition.getAsBoolean()) { + return; + } + } catch (Exception e) { + throw new RuntimeException(e); } waitedTime += waitTime; } diff --git a/src/test/java/com/rabbitmq/client/test/functional/DeadLetterExchange.java b/src/test/java/com/rabbitmq/client/test/functional/DeadLetterExchange.java index 36c09add6a..d7244c7845 100644 --- a/src/test/java/com/rabbitmq/client/test/functional/DeadLetterExchange.java +++ b/src/test/java/com/rabbitmq/client/test/functional/DeadLetterExchange.java @@ -19,12 +19,15 @@ import com.rabbitmq.client.AMQP.BasicProperties; import com.rabbitmq.client.test.BrokerTestCase; import com.rabbitmq.client.test.TestUtils; +import java.util.concurrent.atomic.AtomicReference; import org.junit.Test; import java.io.IOException; import java.util.*; import java.util.concurrent.*; +import static com.rabbitmq.client.test.TestUtils.waitAtMost; +import static java.time.Duration.ofSeconds; import static org.junit.Assert.*; public class DeadLetterExchange extends BrokerTestCase { @@ -403,9 +406,15 @@ public void handleDelivery(String consumerTag, Envelope envelope, channel.queueBind(DLQ, DLX, "test"); publishN(1); - sleep(200); - - GetResponse getResponse = channel.basicGet(DLQ, true); + AtomicReference responseRefeference = new AtomicReference<>(); + waitAtMost( + ofSeconds(1), + () -> { + GetResponse response = channel.basicGet(DLQ, true); + responseRefeference.set(response); + return responseRefeference.get() != null; + }); + GetResponse getResponse = responseRefeference.get(); assertNotNull("Message not dead-lettered", getResponse); assertEquals("test message", new String(getResponse.getBody())); @@ -432,9 +441,15 @@ public void handleDelivery(String consumerTag, Envelope envelope, .headers(headers) .build(), "test message".getBytes()); - sleep(100); - - getResponse = channel.basicGet(DLQ, true); + responseRefeference.set(null); + waitAtMost( + ofSeconds(1), + () -> { + GetResponse response = channel.basicGet(DLQ, true); + responseRefeference.set(response); + return responseRefeference.get() != null; + }); + getResponse = responseRefeference.get(); assertNotNull("Message not dead-lettered", getResponse); assertEquals("test message", new String(getResponse.getBody())); headers = getResponse.getProps().getHeaders(); @@ -453,9 +468,17 @@ public void handleDelivery(String consumerTag, Envelope envelope, new AMQP.BasicProperties.Builder() .headers(headers) .build(), "test message".getBytes()); - sleep(100); - getResponse = channel.basicGet(DLQ, true); + responseRefeference.set(null); + waitAtMost( + ofSeconds(1), + () -> { + GetResponse response = channel.basicGet(DLQ, true); + responseRefeference.set(response); + return responseRefeference.get() != null; + }); + getResponse = responseRefeference.get(); + assertNotNull("Message not dead-lettered", getResponse); assertEquals("test message", new String(getResponse.getBody())); headers = getResponse.getProps().getHeaders(); From ecbe8501f2dd1923bb8e88b5b126a44e75633872 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Arnaud=20Cogolu=C3=A8gnes?= Date: Mon, 25 Oct 2021 11:02:31 +0200 Subject: [PATCH 027/151] Fix test rule (cherry picked from commit 761628ee1ea4f1a90942110d22bb4407ab861549) --- src/test/java/com/rabbitmq/client/test/TestUtils.java | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/test/java/com/rabbitmq/client/test/TestUtils.java b/src/test/java/com/rabbitmq/client/test/TestUtils.java index 72e0b56cea..7544893760 100644 --- a/src/test/java/com/rabbitmq/client/test/TestUtils.java +++ b/src/test/java/com/rabbitmq/client/test/TestUtils.java @@ -343,6 +343,8 @@ public void evaluate() throws Throwable { if (Host.isOnDocker()) { throw new AssumptionViolatedException("Broker is running on Docker"); } + } catch (AssumptionViolatedException e) { + throw e; } catch (Exception e) { throw new AssumptionViolatedException("Could not check whether broker is running on Docker or not", e); } From 99ea9e07588ee147d38f0babe944e956f59a5a46 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Arnaud=20Cogolu=C3=A8gnes?= Date: Mon, 25 Oct 2021 11:21:44 +0200 Subject: [PATCH 028/151] Change/remove usage of some deprecated JDK API API deprecated in Java 16 or more. There are alternatives (e.g. for certificate subject and issuer) for some, but not for all (e.g. usage of the security manager to change thread, which is no big deal as the changes to thread are minor and it is likely nobody cares about such checks nowadays). Fixes #709 (cherry picked from commit 57b61d82dc441d3779547c918f179026d94b5d51) --- .../com/rabbitmq/client/impl/Environment.java | 29 +++++++++---------- .../com/rabbitmq/client/impl/TlsUtils.java | 2 +- 2 files changed, 14 insertions(+), 17 deletions(-) diff --git a/src/main/java/com/rabbitmq/client/impl/Environment.java b/src/main/java/com/rabbitmq/client/impl/Environment.java index 149b9a102e..2676311322 100644 --- a/src/main/java/com/rabbitmq/client/impl/Environment.java +++ b/src/main/java/com/rabbitmq/client/impl/Environment.java @@ -23,32 +23,29 @@ * Package-protected API. */ public class Environment { + + /** + * This method is deprecated and subject to removal in the next major release. + * + * There is no replacement for this method, as it used to use the + * {@link SecurityManager}, which is itself deprecated and subject to removal. + * @deprecated + * @return always returns true + */ + @Deprecated public static boolean isAllowedToModifyThreads() { - try { - SecurityManager sm = System.getSecurityManager(); - if(sm != null) { - sm.checkPermission(new RuntimePermission("modifyThread")); - sm.checkPermission(new RuntimePermission("modifyThreadGroup")); - } - return true; - } catch (SecurityException se) { - return false; - } + return true; } public static Thread newThread(ThreadFactory factory, Runnable runnable, String name) { Thread t = factory.newThread(runnable); - if(isAllowedToModifyThreads()) { - t.setName(name); - } + t.setName(name); return t; } public static Thread newThread(ThreadFactory factory, Runnable runnable, String name, boolean isDaemon) { Thread t = newThread(factory, runnable, name); - if(isAllowedToModifyThreads()) { - t.setDaemon(isDaemon); - } + t.setDaemon(isDaemon); return t; } } diff --git a/src/main/java/com/rabbitmq/client/impl/TlsUtils.java b/src/main/java/com/rabbitmq/client/impl/TlsUtils.java index a11deddc2c..aa103607ec 100644 --- a/src/main/java/com/rabbitmq/client/impl/TlsUtils.java +++ b/src/main/java/com/rabbitmq/client/impl/TlsUtils.java @@ -104,7 +104,7 @@ public static String peerCertificateInfo(Certificate certificate, String prefix) try { return String.format("%s subject: %s, subject alternative names: %s, " + "issuer: %s, not valid after: %s, X.509 usage extensions: %s", - stripCRLF(prefix), stripCRLF(c.getSubjectDN().getName()), stripCRLF(sans(c, ",")), stripCRLF(c.getIssuerDN().getName()), + stripCRLF(prefix), stripCRLF(c.getSubjectX500Principal().getName()), stripCRLF(sans(c, ",")), stripCRLF(c.getIssuerX500Principal().getName()), c.getNotAfter(), stripCRLF(extensions(c))); } catch (Exception e) { return "Error while retrieving " + prefix + " certificate information"; From d87c82feba2d835c35691bfeb97df90926964817 Mon Sep 17 00:00:00 2001 From: ByteAlex Date: Fri, 5 Nov 2021 11:09:45 +0100 Subject: [PATCH 029/151] Parse unsigned byte `B` in ValueReader (cherry picked from commit 15ed3d151e8c8747cd1beb17931eb06d1281d3e7) --- src/main/java/com/rabbitmq/client/impl/ValueReader.java | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/main/java/com/rabbitmq/client/impl/ValueReader.java b/src/main/java/com/rabbitmq/client/impl/ValueReader.java index 1162cc8af0..ed7f41284c 100644 --- a/src/main/java/com/rabbitmq/client/impl/ValueReader.java +++ b/src/main/java/com/rabbitmq/client/impl/ValueReader.java @@ -186,6 +186,9 @@ static Object readFieldValue(DataInputStream in) case 'b': value = in.readByte(); break; + case 'B': + value = in.readUnsignedByte(); + break; case 'd': value = in.readDouble(); break; From 525cb08ae142044c7189c606296e3161b6474c32 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Arnaud=20Cogolu=C3=A8gnes?= Date: Fri, 5 Nov 2021 13:41:55 +0100 Subject: [PATCH 030/151] Fix handshake with NIO on TLS 1.3 The unwrapping does not work the same way between TLS 1.2 and 1.3. This commit makes the unwrapping more reliable by getting the number of bytes consumed in the unwrapping and then set the position of the reading ByteBuffer accordingly to the number of bytes. With TLS 1.3, the unwrapping seems to read the whole content of the buffer and to extract only the first record, so the rewinding is necessary. The commit also adds some debug logging, adds tests on TLS 1.2 and 1.3, and re-arranges the TLS test (add utility class). Fixes #715 (cherry picked from commit 448d3dd0ccb9755db2fccb11f433ddf5b55ca48f) Conflicts: src/test/java/com/rabbitmq/client/test/ssl/HostnameVerification.java --- .../client/impl/nio/SslEngineHelper.java | 101 +++++++++++---- .../rabbitmq/client/test/BrokerTestCase.java | 7 +- .../com/rabbitmq/client/test/TestUtils.java | 45 +++---- .../test/ssl/BadVerifiedConnection.java | 49 +------- .../client/test/ssl/HostnameVerification.java | 35 +----- .../test/ssl/NioTlsUnverifiedConnection.java | 55 +++++---- .../client/test/ssl/TlsConnectionLogging.java | 4 +- .../client/test/ssl/TlsTestUtils.java | 115 ++++++++++++++++++ .../client/test/ssl/UnverifiedConnection.java | 10 +- .../client/test/ssl/VerifiedConnection.java | 93 +++++++------- src/test/resources/logback-test.xml | 2 +- 11 files changed, 302 insertions(+), 214 deletions(-) create mode 100644 src/test/java/com/rabbitmq/client/test/ssl/TlsTestUtils.java diff --git a/src/main/java/com/rabbitmq/client/impl/nio/SslEngineHelper.java b/src/main/java/com/rabbitmq/client/impl/nio/SslEngineHelper.java index 1e7e3a0793..bcefe8b205 100644 --- a/src/main/java/com/rabbitmq/client/impl/nio/SslEngineHelper.java +++ b/src/main/java/com/rabbitmq/client/impl/nio/SslEngineHelper.java @@ -1,4 +1,4 @@ -// Copyright (c) 2007-2020 VMware, Inc. or its affiliates. All rights reserved. +// Copyright (c) 2007-2021 VMware, Inc. or its affiliates. All rights reserved. // // This software, the RabbitMQ Java client library, is triple-licensed under the // Mozilla Public License 2.0 ("MPL"), the GNU General Public License version 2 @@ -23,8 +23,12 @@ import java.nio.channels.ReadableByteChannel; import java.nio.channels.SocketChannel; import java.nio.channels.WritableByteChannel; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; import static javax.net.ssl.SSLEngineResult.HandshakeStatus.FINISHED; +import static javax.net.ssl.SSLEngineResult.HandshakeStatus.NEED_TASK; +import static javax.net.ssl.SSLEngineResult.HandshakeStatus.NEED_WRAP; import static javax.net.ssl.SSLEngineResult.HandshakeStatus.NOT_HANDSHAKING; /** @@ -32,6 +36,8 @@ */ public class SslEngineHelper { + private static final Logger LOGGER = LoggerFactory.getLogger(SslEngineHelper.class); + public static boolean doHandshake(SocketChannel socketChannel, SSLEngine engine) throws IOException { ByteBuffer plainOut = ByteBuffer.allocate(engine.getSession().getApplicationBufferSize()); @@ -39,20 +45,36 @@ public static boolean doHandshake(SocketChannel socketChannel, SSLEngine engine) ByteBuffer cipherOut = ByteBuffer.allocate(engine.getSession().getPacketBufferSize()); ByteBuffer cipherIn = ByteBuffer.allocate(engine.getSession().getPacketBufferSize()); + LOGGER.debug("Starting TLS handshake"); + SSLEngineResult.HandshakeStatus handshakeStatus = engine.getHandshakeStatus(); + LOGGER.debug("Initial handshake status is {}", handshakeStatus); while (handshakeStatus != FINISHED && handshakeStatus != NOT_HANDSHAKING) { + LOGGER.debug("Handshake status is {}", handshakeStatus); switch (handshakeStatus) { case NEED_TASK: + LOGGER.debug("Running tasks"); handshakeStatus = runDelegatedTasks(engine); break; case NEED_UNWRAP: + LOGGER.debug("Unwrapping..."); handshakeStatus = unwrap(cipherIn, plainIn, socketChannel, engine); break; case NEED_WRAP: + LOGGER.debug("Wrapping..."); handshakeStatus = wrap(plainOut, cipherOut, socketChannel, engine); break; + case FINISHED: + break; + case NOT_HANDSHAKING: + break; + default: + throw new SSLException("Unexpected handshake status " + handshakeStatus); } } + + + LOGGER.debug("TLS handshake completed"); return true; } @@ -60,6 +82,7 @@ private static SSLEngineResult.HandshakeStatus runDelegatedTasks(SSLEngine sslEn // FIXME run in executor? Runnable runnable; while ((runnable = sslEngine.getDelegatedTask()) != null) { + LOGGER.debug("Running delegated task"); runnable.run(); } return sslEngine.getHandshakeStatus(); @@ -68,29 +91,57 @@ private static SSLEngineResult.HandshakeStatus runDelegatedTasks(SSLEngine sslEn private static SSLEngineResult.HandshakeStatus unwrap(ByteBuffer cipherIn, ByteBuffer plainIn, ReadableByteChannel channel, SSLEngine sslEngine) throws IOException { SSLEngineResult.HandshakeStatus handshakeStatus = sslEngine.getHandshakeStatus(); - - if (channel.read(cipherIn) < 0) { - throw new SSLException("Could not read from socket channel"); + LOGGER.debug("Handshake status is {} before unwrapping", handshakeStatus); + + LOGGER.debug("Cipher in position {}", cipherIn.position()); + int read; + if (cipherIn.position() == 0) { + LOGGER.debug("Reading from channel"); + read = channel.read(cipherIn); + LOGGER.debug("Read {} byte(s) from channel", read); + if (read < 0) { + throw new SSLException("Could not read from socket channel"); + } + cipherIn.flip(); + } else { + LOGGER.debug("Not reading"); } - cipherIn.flip(); SSLEngineResult.Status status; + SSLEngineResult unwrapResult; do { - SSLEngineResult unwrapResult = sslEngine.unwrap(cipherIn, plainIn); + int positionBeforeUnwrapping = cipherIn.position(); + unwrapResult = sslEngine.unwrap(cipherIn, plainIn); + LOGGER.debug("SSL engine result is {} after unwrapping", unwrapResult); status = unwrapResult.getStatus(); switch (status) { case OK: plainIn.clear(); - handshakeStatus = runDelegatedTasks(sslEngine); + if (unwrapResult.getHandshakeStatus() == NEED_TASK) { + handshakeStatus = runDelegatedTasks(sslEngine); + int newPosition = positionBeforeUnwrapping + unwrapResult.bytesConsumed(); + if (newPosition == cipherIn.limit()) { + LOGGER.debug("Clearing cipherIn because all bytes have been read and unwrapped"); + cipherIn.clear(); + } else { + LOGGER.debug("Setting cipherIn position to {} (limit is {})", newPosition, cipherIn.limit()); + cipherIn.position(positionBeforeUnwrapping + unwrapResult.bytesConsumed()); + } + } else { + handshakeStatus = unwrapResult.getHandshakeStatus(); + } break; case BUFFER_OVERFLOW: throw new SSLException("Buffer overflow during handshake"); case BUFFER_UNDERFLOW: + LOGGER.debug("Buffer underflow"); cipherIn.compact(); - int read = NioHelper.read(channel, cipherIn); + LOGGER.debug("Reading from channel..."); + read = NioHelper.read(channel, cipherIn); if(read <= 0) { retryRead(channel, cipherIn); } + LOGGER.debug("Done reading from channel..."); cipherIn.flip(); break; case CLOSED: @@ -100,9 +151,9 @@ private static SSLEngineResult.HandshakeStatus unwrap(ByteBuffer cipherIn, ByteB throw new SSLException("Unexpected status from " + unwrapResult); } } - while (cipherIn.hasRemaining()); + while (unwrapResult.getHandshakeStatus() != NEED_WRAP && unwrapResult.getHandshakeStatus() != FINISHED); - cipherIn.compact(); + LOGGER.debug("cipherIn position after unwrap {}", cipherIn.position()); return handshakeStatus; } @@ -127,36 +178,32 @@ private static int retryRead(ReadableByteChannel channel, ByteBuffer buffer) thr private static SSLEngineResult.HandshakeStatus wrap(ByteBuffer plainOut, ByteBuffer cipherOut, WritableByteChannel channel, SSLEngine sslEngine) throws IOException { SSLEngineResult.HandshakeStatus handshakeStatus = sslEngine.getHandshakeStatus(); - SSLEngineResult.Status status = sslEngine.wrap(plainOut, cipherOut).getStatus(); - switch (status) { + LOGGER.debug("Handshake status is {} before wrapping", handshakeStatus); + SSLEngineResult result = sslEngine.wrap(plainOut, cipherOut); + LOGGER.debug("SSL engine result is {} after wrapping", result); + switch (result.getStatus()) { case OK: - handshakeStatus = runDelegatedTasks(sslEngine); cipherOut.flip(); while (cipherOut.hasRemaining()) { - channel.write(cipherOut); + int written = channel.write(cipherOut); + LOGGER.debug("Wrote {} byte(s)", written); } cipherOut.clear(); + if (result.getHandshakeStatus() == NEED_TASK) { + handshakeStatus = runDelegatedTasks(sslEngine); + } else { + handshakeStatus = result.getHandshakeStatus(); + } + break; case BUFFER_OVERFLOW: throw new SSLException("Buffer overflow during handshake"); default: - throw new SSLException("Unexpected status " + status); + throw new SSLException("Unexpected status " + result.getStatus()); } return handshakeStatus; } - static int bufferCopy(ByteBuffer from, ByteBuffer to) { - int maxTransfer = Math.min(to.remaining(), from.remaining()); - - ByteBuffer temporaryBuffer = from.duplicate(); - temporaryBuffer.limit(temporaryBuffer.position() + maxTransfer); - to.put(temporaryBuffer); - - from.position(from.position() + maxTransfer); - - return maxTransfer; - } - public static void write(WritableByteChannel socketChannel, SSLEngine engine, ByteBuffer plainOut, ByteBuffer cypherOut) throws IOException { while (plainOut.hasRemaining()) { cypherOut.clear(); diff --git a/src/test/java/com/rabbitmq/client/test/BrokerTestCase.java b/src/test/java/com/rabbitmq/client/test/BrokerTestCase.java index 7c23a3c0e6..37cf436db4 100644 --- a/src/test/java/com/rabbitmq/client/test/BrokerTestCase.java +++ b/src/test/java/com/rabbitmq/client/test/BrokerTestCase.java @@ -1,4 +1,4 @@ -// Copyright (c) 2007-2020 VMware, Inc. or its affiliates. All rights reserved. +// Copyright (c) 2007-2021 VMware, Inc. or its affiliates. All rights reserved. // // This software, the RabbitMQ Java client library, is triple-licensed under the // Mozilla Public License 2.0 ("MPL"), the GNU General Public License version 2 @@ -28,9 +28,7 @@ import org.slf4j.Logger; import org.slf4j.LoggerFactory; -import javax.net.ssl.SSLContext; import java.io.IOException; -import java.security.NoSuchAlgorithmException; import java.util.Map; import java.util.UUID; import java.util.concurrent.TimeoutException; @@ -348,7 +346,4 @@ protected String generateExchangeName() { return "exchange" + UUID.randomUUID().toString(); } - protected SSLContext getSSLContext() throws NoSuchAlgorithmException { - return TestUtils.getSSLContext(); - } } diff --git a/src/test/java/com/rabbitmq/client/test/TestUtils.java b/src/test/java/com/rabbitmq/client/test/TestUtils.java index 7544893760..c488fcff6d 100644 --- a/src/test/java/com/rabbitmq/client/test/TestUtils.java +++ b/src/test/java/com/rabbitmq/client/test/TestUtils.java @@ -1,4 +1,4 @@ -// Copyright (c) 2007-2020 VMware, Inc. or its affiliates. All rights reserved. +// Copyright (c) 2007-2021 VMware, Inc. or its affiliates. All rights reserved. // // This software, the RabbitMQ Java client library, is triple-licensed under the // Mozilla Public License 2.0 ("MPL"), the GNU General Public License version 2 @@ -26,19 +26,15 @@ import org.junit.runners.model.Statement; import org.slf4j.LoggerFactory; -import javax.net.ssl.SSLContext; import java.io.IOException; import java.net.ServerSocket; -import java.security.NoSuchAlgorithmException; import java.time.Duration; -import java.util.Arrays; import java.util.Collection; import java.util.Collections; import java.util.concurrent.Callable; import java.util.concurrent.CountDownLatch; import java.util.concurrent.TimeUnit; import java.util.concurrent.TimeoutException; -import java.util.function.BooleanSupplier; import static org.junit.Assert.assertTrue; @@ -109,22 +105,6 @@ public static void abort(Connection connection) { } } - public static SSLContext getSSLContext() throws NoSuchAlgorithmException { - SSLContext c = null; - - // pick the first protocol available, preferring TLSv1.2, then TLSv1, - // falling back to SSLv3 if running on an ancient/crippled JDK - for (String proto : Arrays.asList("TLSv1.2", "TLSv1", "SSLv3")) { - try { - c = SSLContext.getInstance(proto); - return c; - } catch (NoSuchAlgorithmException x) { - // keep trying - } - } - throw new NoSuchAlgorithmException(); - } - public static TestRule atLeast38() { return new BrokerVersionTestRule("3.8.0"); } @@ -361,4 +341,27 @@ public interface CallableFunction { } + public static boolean basicGetBasicConsume(Connection connection, String queue, final CountDownLatch latch, int msgSize) + throws Exception { + Channel channel = connection.createChannel(); + channel.queueDeclare(queue, false, true, false, null); + channel.queuePurge(queue); + + channel.basicPublish("", queue, null, new byte[msgSize]); + + String tag = channel.basicConsume(queue, false, new DefaultConsumer(channel) { + + @Override + public void handleDelivery(String consumerTag, Envelope envelope, AMQP.BasicProperties properties, byte[] body) throws IOException { + getChannel().basicAck(envelope.getDeliveryTag(), false); + latch.countDown(); + } + }); + + boolean messageReceived = latch.await(20, TimeUnit.SECONDS); + + channel.basicCancel(tag); + + return messageReceived; + } } diff --git a/src/test/java/com/rabbitmq/client/test/ssl/BadVerifiedConnection.java b/src/test/java/com/rabbitmq/client/test/ssl/BadVerifiedConnection.java index 9137213578..fe33af7dec 100644 --- a/src/test/java/com/rabbitmq/client/test/ssl/BadVerifiedConnection.java +++ b/src/test/java/com/rabbitmq/client/test/ssl/BadVerifiedConnection.java @@ -1,4 +1,4 @@ -// Copyright (c) 2007-2020 VMware, Inc. or its affiliates. All rights reserved. +// Copyright (c) 2007-2021 VMware, Inc. or its affiliates. All rights reserved. // // This software, the RabbitMQ Java client library, is triple-licensed under the // Mozilla Public License 2.0 ("MPL"), the GNU General Public License version 2 @@ -15,20 +15,13 @@ package com.rabbitmq.client.test.ssl; -import com.rabbitmq.client.test.TestUtils; import org.junit.Test; -import javax.net.ssl.KeyManagerFactory; import javax.net.ssl.SSLContext; import javax.net.ssl.SSLHandshakeException; -import javax.net.ssl.TrustManagerFactory; -import java.io.FileInputStream; import java.io.IOException; -import java.security.*; -import java.security.cert.CertificateException; import java.util.concurrent.TimeoutException; -import static org.junit.Assert.assertNotNull; import static org.junit.Assert.fail; /** @@ -39,44 +32,10 @@ public class BadVerifiedConnection extends UnverifiedConnection { public void openConnection() throws IOException, TimeoutException { try { - String keystorePath = System.getProperty("test-keystore.empty"); - assertNotNull(keystorePath); - String keystorePasswd = System.getProperty("test-keystore.password"); - assertNotNull(keystorePasswd); - char [] keystorePassword = keystorePasswd.toCharArray(); - - KeyStore tks = KeyStore.getInstance("JKS"); - tks.load(new FileInputStream(keystorePath), keystorePassword); - - TrustManagerFactory tmf = TrustManagerFactory.getInstance("SunX509"); - tmf.init(tks); - - String p12Path = System.getProperty("test-client-cert.path"); - assertNotNull(p12Path); - String p12Passwd = System.getProperty("test-client-cert.password"); - assertNotNull(p12Passwd); - KeyStore ks = KeyStore.getInstance("PKCS12"); - char [] p12Password = p12Passwd.toCharArray(); - ks.load(new FileInputStream(p12Path), p12Password); - - KeyManagerFactory kmf = KeyManagerFactory.getInstance("SunX509"); - kmf.init(ks, p12Password); - - SSLContext c = getSSLContext(); - c.init(kmf.getKeyManagers(), tmf.getTrustManagers(), null); - - connectionFactory = TestUtils.connectionFactory(); + SSLContext c = TlsTestUtils.badVerifiedSslContext(); connectionFactory.useSslProtocol(c); - } catch (NoSuchAlgorithmException ex) { - throw new IOException(ex.toString()); - } catch (KeyManagementException ex) { - throw new IOException(ex.toString()); - } catch (KeyStoreException ex) { - throw new IOException(ex.toString()); - } catch (CertificateException ex) { - throw new IOException(ex.toString()); - } catch (UnrecoverableKeyException ex) { - throw new IOException(ex.toString()); + } catch (Exception ex) { + throw new IOException(ex); } try { diff --git a/src/test/java/com/rabbitmq/client/test/ssl/HostnameVerification.java b/src/test/java/com/rabbitmq/client/test/ssl/HostnameVerification.java index 014c02cfdd..acbfe48260 100644 --- a/src/test/java/com/rabbitmq/client/test/ssl/HostnameVerification.java +++ b/src/test/java/com/rabbitmq/client/test/ssl/HostnameVerification.java @@ -1,4 +1,4 @@ -// Copyright (c) 2007-2020 VMware, Inc. or its affiliates. All rights reserved. +// Copyright (c) 2007-2021 VMware, Inc. or its affiliates. All rights reserved. // // This software, the RabbitMQ Java client library, is triple-licensed under the // Mozilla Public License 2.0 ("MPL"), the GNU General Public License version 2 @@ -24,17 +24,11 @@ import org.junit.runner.RunWith; import org.junit.runners.Parameterized; -import javax.net.ssl.KeyManagerFactory; import javax.net.ssl.SSLContext; import javax.net.ssl.SSLHandshakeException; -import javax.net.ssl.TrustManagerFactory; -import java.io.FileInputStream; -import java.security.KeyStore; import java.util.function.Consumer; -import static com.rabbitmq.client.test.TestUtils.getSSLContext; import static java.util.Collections.singletonList; -import static org.junit.Assert.assertNotNull; import static org.junit.Assert.assertTrue; import static org.junit.Assert.fail; @@ -73,32 +67,7 @@ private static Consumer enableHostnameVerification() { @BeforeClass public static void initCrypto() throws Exception { - String keystorePath = System.getProperty("test-keystore.ca"); - assertNotNull(keystorePath); - String keystorePasswd = System.getProperty("test-keystore.password"); - assertNotNull(keystorePasswd); - char[] keystorePassword = keystorePasswd.toCharArray(); - - KeyStore tks = KeyStore.getInstance("JKS"); - tks.load(new FileInputStream(keystorePath), keystorePassword); - - TrustManagerFactory tmf = TrustManagerFactory.getInstance("SunX509"); - tmf.init(tks); - - String p12Path = System.getProperty("test-client-cert.path"); - assertNotNull(p12Path); - String p12Passwd = System.getProperty("test-client-cert.password"); - assertNotNull(p12Passwd); - - KeyStore ks = KeyStore.getInstance("PKCS12"); - char[] p12Password = p12Passwd.toCharArray(); - ks.load(new FileInputStream(p12Path), p12Password); - - KeyManagerFactory kmf = KeyManagerFactory.getInstance("SunX509"); - kmf.init(ks, p12Password); - - sslContext = getSSLContext(); - sslContext.init(kmf.getKeyManagers(), tmf.getTrustManagers(), null); + sslContext = TlsTestUtils.verifiedSslContext(); } @Test(expected = SSLHandshakeException.class) diff --git a/src/test/java/com/rabbitmq/client/test/ssl/NioTlsUnverifiedConnection.java b/src/test/java/com/rabbitmq/client/test/ssl/NioTlsUnverifiedConnection.java index 29fe35899e..37048739e2 100644 --- a/src/test/java/com/rabbitmq/client/test/ssl/NioTlsUnverifiedConnection.java +++ b/src/test/java/com/rabbitmq/client/test/ssl/NioTlsUnverifiedConnection.java @@ -1,4 +1,4 @@ -// Copyright (c) 2007-2020 VMware, Inc. or its affiliates. All rights reserved. +// Copyright (c) 2007-2021 VMware, Inc. or its affiliates. All rights reserved. // // This software, the RabbitMQ Java client library, is triple-licensed under the // Mozilla Public License 2.0 ("MPL"), the GNU General Public License version 2 @@ -18,6 +18,10 @@ import com.rabbitmq.client.*; import com.rabbitmq.client.impl.nio.NioParams; import com.rabbitmq.client.test.BrokerTestCase; +import com.rabbitmq.client.test.TestUtils; +import java.util.concurrent.atomic.AtomicReference; +import javax.net.ssl.SSLContext; +import javax.net.ssl.TrustManager; import org.junit.Test; import org.slf4j.LoggerFactory; @@ -28,6 +32,8 @@ import java.util.concurrent.TimeoutException; import java.util.concurrent.atomic.AtomicBoolean; +import static com.rabbitmq.client.test.TestUtils.basicGetBasicConsume; +import static org.assertj.core.api.Assertions.assertThat; import static org.junit.Assert.assertTrue; import static org.junit.Assert.fail; @@ -76,6 +82,29 @@ public void connectionGetConsume() throws Exception { assertTrue("Message has not been received", messagesReceived); } + @Test + public void connectionGetConsumeProtocols() throws Exception { + String [] protocols = new String[] {"TLSv1.2", "TLSv1.3"}; + for (String protocol : protocols) { + SSLContext sslContext = SSLContext.getInstance(protocol); + sslContext.init(null, new TrustManager[] {new TrustEverythingTrustManager()}, null); + ConnectionFactory cf = TestUtils.connectionFactory(); + cf.useSslProtocol(sslContext); + cf.useNio(); + AtomicReference engine = new AtomicReference<>(); + cf.setNioParams(new NioParams() + .setSslEngineConfigurator(sslEngine -> engine.set(sslEngine))); + try (Connection c = cf.newConnection()) { + CountDownLatch latch = new CountDownLatch(1); + basicGetBasicConsume(c, QUEUE, latch, 100); + boolean messagesReceived = latch.await(5, TimeUnit.SECONDS); + assertTrue("Message has not been received", messagesReceived); + assertThat(engine.get()).isNotNull(); + assertThat(engine.get().getEnabledProtocols()).contains(protocol); + } + } + } + @Test public void socketChannelConfigurator() throws Exception { ConnectionFactory connectionFactory = new ConnectionFactory(); connectionFactory.useNio(); @@ -119,28 +148,4 @@ private void sendAndVerifyMessage(int size) throws Exception { assertTrue("Message has not been received", messageReceived); } - private boolean basicGetBasicConsume(Connection connection, String queue, final CountDownLatch latch, int msgSize) - throws Exception { - Channel channel = connection.createChannel(); - channel.queueDeclare(queue, false, false, false, null); - channel.queuePurge(queue); - - channel.basicPublish("", queue, null, new byte[msgSize]); - - String tag = channel.basicConsume(queue, false, new DefaultConsumer(channel) { - - @Override - public void handleDelivery(String consumerTag, Envelope envelope, AMQP.BasicProperties properties, byte[] body) throws IOException { - getChannel().basicAck(envelope.getDeliveryTag(), false); - latch.countDown(); - } - }); - - boolean messageReceived = latch.await(20, TimeUnit.SECONDS); - - channel.basicCancel(tag); - - return messageReceived; - } - } diff --git a/src/test/java/com/rabbitmq/client/test/ssl/TlsConnectionLogging.java b/src/test/java/com/rabbitmq/client/test/ssl/TlsConnectionLogging.java index 49b9ac3ad9..4298f18a9a 100644 --- a/src/test/java/com/rabbitmq/client/test/ssl/TlsConnectionLogging.java +++ b/src/test/java/com/rabbitmq/client/test/ssl/TlsConnectionLogging.java @@ -1,4 +1,4 @@ -// Copyright (c) 2019-2020 VMware, Inc. or its affiliates. All rights reserved. +// Copyright (c) 2019-2021 VMware, Inc. or its affiliates. All rights reserved. // // This software, the RabbitMQ Java client library, is triple-licensed under the // Mozilla Public License 2.0 ("MPL"), the GNU General Public License version 2 @@ -66,7 +66,7 @@ public static Function> nio() { @Test public void certificateInfoAreProperlyExtracted() throws Exception { - SSLContext sslContext = TestUtils.getSSLContext(); + SSLContext sslContext = TlsTestUtils.getSSLContext(); sslContext.init(null, new TrustManager[]{new AlwaysTrustTrustManager()}, null); ConnectionFactory connectionFactory = TestUtils.connectionFactory(); connectionFactory.useSslProtocol(sslContext); diff --git a/src/test/java/com/rabbitmq/client/test/ssl/TlsTestUtils.java b/src/test/java/com/rabbitmq/client/test/ssl/TlsTestUtils.java new file mode 100644 index 0000000000..891bec7f04 --- /dev/null +++ b/src/test/java/com/rabbitmq/client/test/ssl/TlsTestUtils.java @@ -0,0 +1,115 @@ +// Copyright (c) 2021 VMware, Inc. or its affiliates. All rights reserved. +// +// This software, the RabbitMQ Java client library, is triple-licensed under the +// Mozilla Public License 2.0 ("MPL"), the GNU General Public License version 2 +// ("GPL") and the Apache License version 2 ("ASL"). For the MPL, please see +// LICENSE-MPL-RabbitMQ. For the GPL, please see LICENSE-GPL2. For the ASL, +// please see LICENSE-APACHE2. +// +// This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY KIND, +// either express or implied. See the LICENSE file for specific language governing +// rights and limitations of this software. +// +// If you have any questions regarding licensing, please contact us at +// info@rabbitmq.com. + +package com.rabbitmq.client.test.ssl; + +import static org.junit.Assert.assertNotNull; + +import java.io.FileInputStream; +import java.security.KeyStore; +import java.security.NoSuchAlgorithmException; +import java.util.Arrays; +import javax.net.ssl.KeyManagerFactory; +import javax.net.ssl.SSLContext; +import javax.net.ssl.TrustManagerFactory; + +class TlsTestUtils { + + private TlsTestUtils() {} + + static SSLContext badVerifiedSslContext() throws Exception { + return verifiedSslContext(() -> getSSLContext(), emptyKeystoreCa()); + } + + static SSLContext verifiedSslContext() throws Exception { + return verifiedSslContext(() -> getSSLContext(), keystoreCa()); + } + + static SSLContext verifiedSslContext(CallableSupplier sslContextSupplier) throws Exception { + return verifiedSslContext(sslContextSupplier, keystoreCa()); + } + + static SSLContext verifiedSslContext(CallableSupplier sslContextSupplier, String keystorePath) throws Exception { + // for local testing, run ./mvnw test-compile -Dtest-tls-certs.dir=/tmp/tls-gen/basic + // (generates the Java keystores) + assertNotNull(keystorePath); + String keystorePasswd = keystorePassword(); + assertNotNull(keystorePasswd); + char [] keystorePassword = keystorePasswd.toCharArray(); + + KeyStore tks = KeyStore.getInstance("JKS"); + tks.load(new FileInputStream(keystorePath), keystorePassword); + + TrustManagerFactory tmf = TrustManagerFactory.getInstance("SunX509"); + tmf.init(tks); + + String p12Path = clientCertPath(); + assertNotNull(p12Path); + String p12Passwd = clientCertPassword(); + assertNotNull(p12Passwd); + KeyStore ks = KeyStore.getInstance("PKCS12"); + char [] p12Password = p12Passwd.toCharArray(); + ks.load(new FileInputStream(p12Path), p12Password); + + KeyManagerFactory kmf = KeyManagerFactory.getInstance("SunX509"); + kmf.init(ks, p12Password); + + SSLContext c = sslContextSupplier.get(); + c.init(kmf.getKeyManagers(), tmf.getTrustManagers(), null); + return c; + } + + static String keystoreCa() { + return System.getProperty("test-keystore.ca", "./target/ca.keystore"); + } + + static String emptyKeystoreCa() { + return System.getProperty("test-keystore.empty", "./target/empty.keystore"); + } + + static String keystorePassword() { + return System.getProperty("test-keystore.password", "bunnies"); + } + + static String clientCertPath() { + return System.getProperty("test-client-cert.path", "/tmp/tls-gen/basic/client/keycert.p12"); + } + + static String clientCertPassword() { + return System.getProperty("test-client-cert.password", ""); + } + + public static SSLContext getSSLContext() throws NoSuchAlgorithmException { + SSLContext c; + + // pick the first protocol available, preferring TLSv1.2, then TLSv1, + // falling back to SSLv3 if running on an ancient/crippled JDK + for (String proto : Arrays.asList("TLSv1.3", "TLSv1.2", "TLSv1", "SSLv3")) { + try { + c = SSLContext.getInstance(proto); + return c; + } catch (NoSuchAlgorithmException x) { + // keep trying + } + } + throw new NoSuchAlgorithmException(); + } + + @FunctionalInterface + interface CallableSupplier { + + T get() throws Exception; + } +} diff --git a/src/test/java/com/rabbitmq/client/test/ssl/UnverifiedConnection.java b/src/test/java/com/rabbitmq/client/test/ssl/UnverifiedConnection.java index a14a257c24..39e1e90ba5 100644 --- a/src/test/java/com/rabbitmq/client/test/ssl/UnverifiedConnection.java +++ b/src/test/java/com/rabbitmq/client/test/ssl/UnverifiedConnection.java @@ -1,4 +1,4 @@ -// Copyright (c) 2007-2020 VMware, Inc. or its affiliates. All rights reserved. +// Copyright (c) 2007-2021 VMware, Inc. or its affiliates. All rights reserved. // // This software, the RabbitMQ Java client library, is triple-licensed under the // Mozilla Public License 2.0 ("MPL"), the GNU General Public License version 2 @@ -21,8 +21,6 @@ import org.slf4j.LoggerFactory; import java.io.IOException; -import java.security.KeyManagementException; -import java.security.NoSuchAlgorithmException; import java.util.concurrent.TimeoutException; import static org.junit.Assert.*; @@ -37,10 +35,8 @@ public void openConnection() throws IOException, TimeoutException { try { connectionFactory.useSslProtocol(); - } catch (NoSuchAlgorithmException ex) { - throw new IOException(ex.toString()); - } catch (KeyManagementException ex) { - throw new IOException(ex.toString()); + } catch (Exception ex) { + throw new IOException(ex); } int attempt = 0; diff --git a/src/test/java/com/rabbitmq/client/test/ssl/VerifiedConnection.java b/src/test/java/com/rabbitmq/client/test/ssl/VerifiedConnection.java index 50d4d9003b..0f82fb1194 100644 --- a/src/test/java/com/rabbitmq/client/test/ssl/VerifiedConnection.java +++ b/src/test/java/com/rabbitmq/client/test/ssl/VerifiedConnection.java @@ -1,4 +1,4 @@ -// Copyright (c) 2007-2020 VMware, Inc. or its affiliates. All rights reserved. +// Copyright (c) 2007-2021 VMware, Inc. or its affiliates. All rights reserved. // // This software, the RabbitMQ Java client library, is triple-licensed under the // Mozilla Public License 2.0 ("MPL"), the GNU General Public License version 2 @@ -15,25 +15,25 @@ package com.rabbitmq.client.test.ssl; -import static org.junit.Assert.assertNotNull; +import static org.assertj.core.api.Assertions.assertThat; +import static org.junit.Assert.assertTrue; import static org.junit.Assert.fail; -import java.io.FileInputStream; +import com.rabbitmq.client.Connection; +import com.rabbitmq.client.impl.nio.NioParams; import java.io.IOException; -import java.security.KeyManagementException; -import java.security.KeyStore; -import java.security.KeyStoreException; -import java.security.NoSuchAlgorithmException; -import java.security.UnrecoverableKeyException; -import java.security.cert.CertificateException; +import java.util.concurrent.CountDownLatch; +import java.util.concurrent.TimeUnit; import java.util.concurrent.TimeoutException; -import javax.net.ssl.KeyManagerFactory; +import java.util.concurrent.atomic.AtomicReference; +import java.util.function.Supplier; import javax.net.ssl.SSLContext; -import javax.net.ssl.TrustManagerFactory; +import javax.net.ssl.SSLSocket; import com.rabbitmq.client.ConnectionFactory; import com.rabbitmq.client.test.TestUtils; +import org.junit.Test; import org.slf4j.LoggerFactory; /** @@ -45,44 +45,11 @@ public class VerifiedConnection extends UnverifiedConnection { public void openConnection() throws IOException, TimeoutException { try { - String keystorePath = System.getProperty("test-keystore.ca"); - assertNotNull(keystorePath); - String keystorePasswd = System.getProperty("test-keystore.password"); - assertNotNull(keystorePasswd); - char [] keystorePassword = keystorePasswd.toCharArray(); - - KeyStore tks = KeyStore.getInstance("JKS"); - tks.load(new FileInputStream(keystorePath), keystorePassword); - - TrustManagerFactory tmf = TrustManagerFactory.getInstance("SunX509"); - tmf.init(tks); - - String p12Path = System.getProperty("test-client-cert.path"); - assertNotNull(p12Path); - String p12Passwd = System.getProperty("test-client-cert.password"); - assertNotNull(p12Passwd); - KeyStore ks = KeyStore.getInstance("PKCS12"); - char [] p12Password = p12Passwd.toCharArray(); - ks.load(new FileInputStream(p12Path), p12Password); - - KeyManagerFactory kmf = KeyManagerFactory.getInstance("SunX509"); - kmf.init(ks, p12Password); - - SSLContext c = getSSLContext(); - c.init(kmf.getKeyManagers(), tmf.getTrustManagers(), null); - + SSLContext c = TlsTestUtils.verifiedSslContext(); connectionFactory = TestUtils.connectionFactory(); connectionFactory.useSslProtocol(c); - } catch (NoSuchAlgorithmException ex) { - throw new IOException(ex.toString()); - } catch (KeyManagementException ex) { - throw new IOException(ex.toString()); - } catch (KeyStoreException ex) { - throw new IOException(ex.toString()); - } catch (CertificateException ex) { - throw new IOException(ex.toString()); - } catch (UnrecoverableKeyException ex) { - throw new IOException(ex.toString()); + } catch (Exception ex) { + throw new IOException(ex); } int attempt = 0; @@ -99,4 +66,36 @@ public void openConnection() fail("Couldn't open TLS connection after 3 attempts"); } } + + @Test + public void connectionGetConsumeProtocols() throws Exception { + String [] protocols = new String[] {"TLSv1.2", "TLSv1.3"}; + for (String protocol : protocols) { + SSLContext sslContext = SSLContext.getInstance(protocol); + ConnectionFactory cf = TestUtils.connectionFactory(); + cf.useSslProtocol(TlsTestUtils.verifiedSslContext(() -> sslContext)); + AtomicReference> protocolsSupplier = new AtomicReference<>(); + if (TestUtils.USE_NIO) { + cf.useNio(); + cf.setNioParams(new NioParams() + .setSslEngineConfigurator(sslEngine -> { + protocolsSupplier.set(() -> sslEngine.getEnabledProtocols()); + })); + } else { + cf.setSocketConfigurator(socket -> { + SSLSocket s = (SSLSocket) socket; + protocolsSupplier.set(() -> s.getEnabledProtocols()); + }); + } + try (Connection c = cf.newConnection()) { + CountDownLatch latch = new CountDownLatch(1); + TestUtils.basicGetBasicConsume(c, VerifiedConnection.class.getName(), latch, 100); + boolean messagesReceived = latch.await(5, TimeUnit.SECONDS); + assertTrue("Message has not been received", messagesReceived); + assertThat(protocolsSupplier.get()).isNotNull(); + assertThat(protocolsSupplier.get().get()).contains(protocol); + } + } + } + } diff --git a/src/test/resources/logback-test.xml b/src/test/resources/logback-test.xml index 4bd2e37606..ee88f442c2 100644 --- a/src/test/resources/logback-test.xml +++ b/src/test/resources/logback-test.xml @@ -5,7 +5,7 @@ - + \ No newline at end of file From 830bdc6a9cef7d74e2c09831d565d974bb4bd34f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Arnaud=20Cogolu=C3=A8gnes?= Date: Mon, 8 Nov 2021 09:32:24 +0100 Subject: [PATCH 031/151] Test TLS 1.3 only if available TLS 1.3 has not been backported to all Java version (e.g. on 9 and 10), so this commit checks if the protocol is available before running the test. References #715 (cherry picked from commit 23961d5d0557a13105e099d2a90d90c4e96ab006) --- .../client/test/ssl/NioTlsUnverifiedConnection.java | 8 +++++++- .../com/rabbitmq/client/test/ssl/TlsTestUtils.java | 12 ++++++++++++ .../rabbitmq/client/test/ssl/VerifiedConnection.java | 8 +++++++- 3 files changed, 26 insertions(+), 2 deletions(-) diff --git a/src/test/java/com/rabbitmq/client/test/ssl/NioTlsUnverifiedConnection.java b/src/test/java/com/rabbitmq/client/test/ssl/NioTlsUnverifiedConnection.java index 37048739e2..bc143bc811 100644 --- a/src/test/java/com/rabbitmq/client/test/ssl/NioTlsUnverifiedConnection.java +++ b/src/test/java/com/rabbitmq/client/test/ssl/NioTlsUnverifiedConnection.java @@ -19,7 +19,10 @@ import com.rabbitmq.client.impl.nio.NioParams; import com.rabbitmq.client.test.BrokerTestCase; import com.rabbitmq.client.test.TestUtils; +import java.util.Collection; import java.util.concurrent.atomic.AtomicReference; +import java.util.stream.Collectors; +import java.util.stream.Stream; import javax.net.ssl.SSLContext; import javax.net.ssl.TrustManager; import org.junit.Test; @@ -84,7 +87,10 @@ public void connectionGetConsume() throws Exception { @Test public void connectionGetConsumeProtocols() throws Exception { - String [] protocols = new String[] {"TLSv1.2", "TLSv1.3"}; + Collection availableProtocols = TlsTestUtils.availableTlsProtocols(); + Collection protocols = Stream.of("TLSv1.2", "TLSv1.3") + .filter(p -> availableProtocols.contains(p)) + .collect(Collectors.toList()); for (String protocol : protocols) { SSLContext sslContext = SSLContext.getInstance(protocol); sslContext.init(null, new TrustManager[] {new TrustEverythingTrustManager()}, null); diff --git a/src/test/java/com/rabbitmq/client/test/ssl/TlsTestUtils.java b/src/test/java/com/rabbitmq/client/test/ssl/TlsTestUtils.java index 891bec7f04..6e633ce664 100644 --- a/src/test/java/com/rabbitmq/client/test/ssl/TlsTestUtils.java +++ b/src/test/java/com/rabbitmq/client/test/ssl/TlsTestUtils.java @@ -21,6 +21,8 @@ import java.security.KeyStore; import java.security.NoSuchAlgorithmException; import java.util.Arrays; +import java.util.Collection; +import java.util.stream.Collectors; import javax.net.ssl.KeyManagerFactory; import javax.net.ssl.SSLContext; import javax.net.ssl.TrustManagerFactory; @@ -107,6 +109,16 @@ public static SSLContext getSSLContext() throws NoSuchAlgorithmException { throw new NoSuchAlgorithmException(); } + static Collection availableTlsProtocols() { + try { + String[] protocols = SSLContext.getDefault().getSupportedSSLParameters().getProtocols(); + return Arrays.stream(protocols).filter(p -> p.toLowerCase().startsWith("tls")).collect( + Collectors.toList()); + } catch (NoSuchAlgorithmException e) { + throw new RuntimeException(e); + } + } + @FunctionalInterface interface CallableSupplier { diff --git a/src/test/java/com/rabbitmq/client/test/ssl/VerifiedConnection.java b/src/test/java/com/rabbitmq/client/test/ssl/VerifiedConnection.java index 0f82fb1194..9accac4459 100644 --- a/src/test/java/com/rabbitmq/client/test/ssl/VerifiedConnection.java +++ b/src/test/java/com/rabbitmq/client/test/ssl/VerifiedConnection.java @@ -22,12 +22,15 @@ import com.rabbitmq.client.Connection; import com.rabbitmq.client.impl.nio.NioParams; import java.io.IOException; +import java.util.Collection; import java.util.concurrent.CountDownLatch; import java.util.concurrent.TimeUnit; import java.util.concurrent.TimeoutException; import java.util.concurrent.atomic.AtomicReference; import java.util.function.Supplier; +import java.util.stream.Collectors; +import java.util.stream.Stream; import javax.net.ssl.SSLContext; import javax.net.ssl.SSLSocket; @@ -69,7 +72,10 @@ public void openConnection() @Test public void connectionGetConsumeProtocols() throws Exception { - String [] protocols = new String[] {"TLSv1.2", "TLSv1.3"}; + Collection availableProtocols = TlsTestUtils.availableTlsProtocols(); + Collection protocols = Stream.of("TLSv1.2", "TLSv1.3") + .filter(p -> availableProtocols.contains(p)) + .collect(Collectors.toList()); for (String protocol : protocols) { SSLContext sslContext = SSLContext.getInstance(protocol); ConnectionFactory cf = TestUtils.connectionFactory(); From 7e830e9c9641bf49bdadc73715e9dc9ca12913a5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Arnaud=20Cogolu=C3=A8gnes?= Date: Mon, 8 Nov 2021 09:46:22 +0100 Subject: [PATCH 032/151] Fix usage of NioParams setter in test References #396,#715 --- .../client/test/ssl/NioTlsUnverifiedConnection.java | 5 +++-- .../com/rabbitmq/client/test/ssl/VerifiedConnection.java | 9 +++++---- 2 files changed, 8 insertions(+), 6 deletions(-) diff --git a/src/test/java/com/rabbitmq/client/test/ssl/NioTlsUnverifiedConnection.java b/src/test/java/com/rabbitmq/client/test/ssl/NioTlsUnverifiedConnection.java index bc143bc811..132cac31cc 100644 --- a/src/test/java/com/rabbitmq/client/test/ssl/NioTlsUnverifiedConnection.java +++ b/src/test/java/com/rabbitmq/client/test/ssl/NioTlsUnverifiedConnection.java @@ -98,8 +98,9 @@ public void connectionGetConsumeProtocols() throws Exception { cf.useSslProtocol(sslContext); cf.useNio(); AtomicReference engine = new AtomicReference<>(); - cf.setNioParams(new NioParams() - .setSslEngineConfigurator(sslEngine -> engine.set(sslEngine))); + NioParams nioParams = new NioParams(); + nioParams.setSslEngineConfigurator(sslEngine -> engine.set(sslEngine)); + cf.setNioParams(nioParams); try (Connection c = cf.newConnection()) { CountDownLatch latch = new CountDownLatch(1); basicGetBasicConsume(c, QUEUE, latch, 100); diff --git a/src/test/java/com/rabbitmq/client/test/ssl/VerifiedConnection.java b/src/test/java/com/rabbitmq/client/test/ssl/VerifiedConnection.java index 9accac4459..1df24d83a9 100644 --- a/src/test/java/com/rabbitmq/client/test/ssl/VerifiedConnection.java +++ b/src/test/java/com/rabbitmq/client/test/ssl/VerifiedConnection.java @@ -83,10 +83,11 @@ public void connectionGetConsumeProtocols() throws Exception { AtomicReference> protocolsSupplier = new AtomicReference<>(); if (TestUtils.USE_NIO) { cf.useNio(); - cf.setNioParams(new NioParams() - .setSslEngineConfigurator(sslEngine -> { - protocolsSupplier.set(() -> sslEngine.getEnabledProtocols()); - })); + NioParams nioParams = new NioParams(); + nioParams.setSslEngineConfigurator( + sslEngine -> protocolsSupplier.set(() -> sslEngine.getEnabledProtocols()) + ); + cf.setNioParams(nioParams); } else { cf.setSocketConfigurator(socket -> { SSLSocket s = (SSLSocket) socket; From 2002ba6c11345ec5604c7a0c221c2660b6a4d872 Mon Sep 17 00:00:00 2001 From: pivotal-rabbitmq-ci Date: Mon, 8 Nov 2021 10:27:56 +0000 Subject: [PATCH 033/151] [maven-release-plugin] prepare release v5.14.0.RC1 --- pom.xml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/pom.xml b/pom.xml index 721405e4a5..d3147ea977 100644 --- a/pom.xml +++ b/pom.xml @@ -4,7 +4,7 @@ com.rabbitmq amqp-client - 5.14.0-SNAPSHOT + 5.14.0.RC1 jar RabbitMQ Java Client @@ -42,7 +42,7 @@ https://github.com/rabbitmq/rabbitmq-java-client scm:git:git://github.com/rabbitmq/rabbitmq-java-client.git scm:git:git@github.com:rabbitmq/rabbitmq-java-client.git - HEAD + v5.14.0.RC1 From 6b80f188d89b0b00750ccb5e859cbf65a4ce32ca Mon Sep 17 00:00:00 2001 From: pivotal-rabbitmq-ci Date: Mon, 8 Nov 2021 10:27:58 +0000 Subject: [PATCH 034/151] [maven-release-plugin] prepare for next development iteration --- pom.xml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/pom.xml b/pom.xml index d3147ea977..721405e4a5 100644 --- a/pom.xml +++ b/pom.xml @@ -4,7 +4,7 @@ com.rabbitmq amqp-client - 5.14.0.RC1 + 5.14.0-SNAPSHOT jar RabbitMQ Java Client @@ -42,7 +42,7 @@ https://github.com/rabbitmq/rabbitmq-java-client scm:git:git://github.com/rabbitmq/rabbitmq-java-client.git scm:git:git@github.com:rabbitmq/rabbitmq-java-client.git - v5.14.0.RC1 + HEAD From fba1fd92a9190399461287072973b33593b749ea Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Arnaud=20Cogolu=C3=A8gnes?= Date: Mon, 8 Nov 2021 11:30:10 +0100 Subject: [PATCH 035/151] Set release version to 5.14.0.RC2 --- release-versions.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/release-versions.txt b/release-versions.txt index 19d9bee27b..cb85e0b3e9 100644 --- a/release-versions.txt +++ b/release-versions.txt @@ -1,3 +1,3 @@ -RELEASE_VERSION="5.14.0.RC1" +RELEASE_VERSION="5.14.0.RC2" DEVELOPMENT_VERSION="5.14.0-SNAPSHOT" RELEASE_BRANCH="5.x.x-stable" From 17de251bf381943f39f558f1bd97900c847bcecd Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Arnaud=20Cogolu=C3=A8gnes?= Date: Mon, 15 Nov 2021 10:04:21 +0100 Subject: [PATCH 036/151] Set release version to 5.14.0 --- release-versions.txt | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/release-versions.txt b/release-versions.txt index cb85e0b3e9..a93c142519 100644 --- a/release-versions.txt +++ b/release-versions.txt @@ -1,3 +1,3 @@ -RELEASE_VERSION="5.14.0.RC2" -DEVELOPMENT_VERSION="5.14.0-SNAPSHOT" +RELEASE_VERSION="5.14.0" +DEVELOPMENT_VERSION="5.15.0-SNAPSHOT" RELEASE_BRANCH="5.x.x-stable" From dd03c79f4d30f32e4871188b52f0148b24846ad2 Mon Sep 17 00:00:00 2001 From: pivotal-rabbitmq-ci Date: Mon, 15 Nov 2021 09:09:20 +0000 Subject: [PATCH 037/151] [maven-release-plugin] prepare release v5.14.0 --- pom.xml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/pom.xml b/pom.xml index 721405e4a5..04bbaf2a16 100644 --- a/pom.xml +++ b/pom.xml @@ -4,7 +4,7 @@ com.rabbitmq amqp-client - 5.14.0-SNAPSHOT + 5.14.0 jar RabbitMQ Java Client @@ -42,7 +42,7 @@ https://github.com/rabbitmq/rabbitmq-java-client scm:git:git://github.com/rabbitmq/rabbitmq-java-client.git scm:git:git@github.com:rabbitmq/rabbitmq-java-client.git - HEAD + v5.14.0 From 69336683f91b2ac75bf80eecfb49974c2be7333b Mon Sep 17 00:00:00 2001 From: pivotal-rabbitmq-ci Date: Mon, 15 Nov 2021 09:09:22 +0000 Subject: [PATCH 038/151] [maven-release-plugin] prepare for next development iteration --- pom.xml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/pom.xml b/pom.xml index 04bbaf2a16..32984a40fe 100644 --- a/pom.xml +++ b/pom.xml @@ -4,7 +4,7 @@ com.rabbitmq amqp-client - 5.14.0 + 5.15.0-SNAPSHOT jar RabbitMQ Java Client @@ -42,7 +42,7 @@ https://github.com/rabbitmq/rabbitmq-java-client scm:git:git://github.com/rabbitmq/rabbitmq-java-client.git scm:git:git@github.com:rabbitmq/rabbitmq-java-client.git - v5.14.0 + HEAD From 412cfa8b8bc647a5fa73c17dcb9085290987cad0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Arnaud=20Cogolu=C3=A8gnes?= Date: Mon, 15 Nov 2021 15:56:45 +0100 Subject: [PATCH 039/151] Bump Micrometer to 1.8.0 References #717 (cherry picked from commit 3d1c55c4c82ca112d304f4f9e87582d7052be07d) --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index 32984a40fe..a95126b0ec 100644 --- a/pom.xml +++ b/pom.xml @@ -56,7 +56,7 @@ 1.7.32 4.2.4 - 1.7.5 + 1.8.0 2.13.0 1.2.6 4.13.2 From 08039edeb7de7deb20a61b4dbc57b3c72a4803f1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Arnaud=20Cogolu=C3=A8gnes?= Date: Mon, 15 Nov 2021 15:57:28 +0100 Subject: [PATCH 040/151] Bump logback to 1.2.7 (test dependency) (cherry picked from commit 45f761eb7ce041bb1fd0eaf88282e68f0a3d2d4d) --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index a95126b0ec..d51ed53f39 100644 --- a/pom.xml +++ b/pom.xml @@ -58,7 +58,7 @@ 4.2.4 1.8.0 2.13.0 - 1.2.6 + 1.2.7 4.13.2 4.0.0 3.21.0 From 670f271c23336bce08f3421ae120828607016211 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Arnaud=20Cogolu=C3=A8gnes?= Date: Mon, 13 Dec 2021 11:23:34 +0100 Subject: [PATCH 041/151] Bump Maven Groovy Plugin to 2.1.1 To avoid error on Java 18, it fails because of the usage of the SecurityManager (deprecated). (cherry picked from commit ba4ebbaaf17bad8ebc7503bc01a38fc711930bf7) --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index d51ed53f39..57187f8679 100644 --- a/pom.xml +++ b/pom.xml @@ -70,7 +70,7 @@ 2.3 3.1.0 3.0.1 - 2.0 + 2.1.1 2.4.8 1.5 1.12 From 1106a8ba45a91cefa2242630336dc9a6b97848a4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Arnaud=20Cogolu=C3=A8gnes?= Date: Mon, 13 Dec 2021 13:57:40 +0100 Subject: [PATCH 042/151] Use count down latch in test To avoid using Thread#stop(), which is deprecated since 1998. The test does not explain why or if Thread#stop() is necessary to the test. It's unlikely as the target thread has stopped already when stop is called in the test. (cherry picked from commit 6aaa203aa979307e7dc9326b7d9f0f077d8cc390) --- .../rabbitmq/client/test/Bug20004Test.java | 89 ++++++++----------- 1 file changed, 39 insertions(+), 50 deletions(-) diff --git a/src/test/java/com/rabbitmq/client/test/Bug20004Test.java b/src/test/java/com/rabbitmq/client/test/Bug20004Test.java index 63e237d4b1..d14e1d3e74 100644 --- a/src/test/java/com/rabbitmq/client/test/Bug20004Test.java +++ b/src/test/java/com/rabbitmq/client/test/Bug20004Test.java @@ -1,4 +1,4 @@ -// Copyright (c) 2007-2020 VMware, Inc. or its affiliates. All rights reserved. +// Copyright (c) 2007-2021 VMware, Inc. or its affiliates. All rights reserved. // // This software, the RabbitMQ Java client library, is triple-licensed under the // Mozilla Public License 2.0 ("MPL"), the GNU General Public License version 2 @@ -15,66 +15,55 @@ package com.rabbitmq.client.test; -import org.junit.Test; +import static org.junit.Assert.assertNull; +import static org.junit.Assert.assertTrue; import java.io.IOException; - -import static org.junit.Assert.*; +import java.util.concurrent.CountDownLatch; +import java.util.concurrent.TimeUnit; +import org.junit.Test; /** - * Test for bug 20004 - deadlock through internal synchronization on - * the channel object. This is more properly a unit test, but since it - * requires a connection to a broker, it's grouped with the functional - * tests. - *

- * Test calls channel.queueDeclare, while synchronising on channel, from - * an independent thread. + * Test for bug 20004 - deadlock through internal synchronization on the channel object. This is + * more properly a unit test, but since it requires a connection to a broker, it's grouped with the + * functional tests. + * + *

Test calls channel.queueDeclare, while synchronising on channel, from an independent thread. */ public class Bug20004Test extends BrokerTestCase { - private volatile Exception caughtException = null; - private volatile boolean completed = false; - private volatile boolean created = false; + private volatile Exception caughtException = null; + private volatile boolean created = false; - protected void releaseResources() - throws IOException - { - if (created) { - channel.queueDelete("Bug20004Test"); - } + protected void releaseResources() throws IOException { + if (created) { + channel.queueDelete("Bug20004Test"); } + } - @SuppressWarnings("deprecation") - @Test public void bug20004() throws IOException - { - final Bug20004Test testInstance = this; + @Test + public void bug20004() throws InterruptedException { + final Bug20004Test testInstance = this; + CountDownLatch completedLatch = new CountDownLatch(1); - Thread declaringThread = new Thread(new Runnable() { - public void run() { - try { - synchronized (channel) { - channel.queueDeclare("Bug20004Test", false, false, false, null); - testInstance.created = true; - } - } catch (Exception e) { - testInstance.caughtException = e; + Thread declaringThread = + new Thread( + () -> { + try { + synchronized (channel) { + channel.queueDeclare("Bug20004Test", false, false, false, null); + testInstance.created = true; } - testInstance.completed = true; - } - }); - declaringThread.start(); + } catch (Exception e) { + testInstance.caughtException = e; + } + completedLatch.countDown(); + }); + declaringThread.start(); - // poll (100ms) for `completed`, up to 5s - long endTime = System.currentTimeMillis() + 5000; - while (!completed && (System.currentTimeMillis() < endTime)) { - try { - Thread.sleep(100); - } catch (InterruptedException ie) {} - } + boolean completed = completedLatch.await(5, TimeUnit.SECONDS); - declaringThread.stop(); // see bug 20012. - - assertTrue("Deadlock detected?", completed); - assertNull("queueDeclare threw an exception", caughtException); - assertTrue("unknown sequence of events", created); - } + assertTrue("Deadlock detected?", completed); + assertNull("queueDeclare threw an exception", caughtException); + assertTrue("unknown sequence of events", created); + } } From 3f541ead56b8190d80fe3965397c3afb109b9f7d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Arnaud=20Cogolu=C3=A8gnes?= Date: Mon, 3 Jan 2022 10:53:02 +0100 Subject: [PATCH 043/151] Bump dependencies References #717 (cherry picked from commit 7eb4d3fe32a85234c629ef4493238fc677be0655) --- pom.xml | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/pom.xml b/pom.xml index 57187f8679..40469c0241 100644 --- a/pom.xml +++ b/pom.xml @@ -55,9 +55,9 @@ UTF-8 1.7.32 - 4.2.4 - 1.8.0 - 2.13.0 + 4.2.7 + 1.8.1 + 2.13.1 1.2.7 4.13.2 4.0.0 From a7c5d5dc5d5cc0266709eb3e4ebaa869a73e894e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Arnaud=20Cogolu=C3=A8gnes?= Date: Mon, 3 Jan 2022 10:53:51 +0100 Subject: [PATCH 044/151] Bump test dependencies (cherry picked from commit 32dfd0fb338a3ff1db2c79dfeb42c9fd451284a0) --- pom.xml | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/pom.xml b/pom.xml index 40469c0241..dae3fc505c 100644 --- a/pom.xml +++ b/pom.xml @@ -58,12 +58,12 @@ 4.2.7 1.8.1 2.13.1 - 1.2.7 + 1.2.10 4.13.2 - 4.0.0 - 3.21.0 + 4.2.0 + 3.22.0 9.4.44.v20210927 - 1.69 + 1.70 3.2.0 2.5.3 From b04e8172f9ad1e4a9eb2cad01161dadfd74525f3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Arnaud=20Cogolu=C3=A8gnes?= Date: Wed, 12 Jan 2022 16:56:41 +0100 Subject: [PATCH 045/151] Enforce connection timeout in NIO TLS handshake The handshake is in blocking mode and reading from a channel in this mode does not honor so_timeout but using temporary channels based on the socket input/output streams offers a decent workaround for this stage. Fixes #719 (cherry picked from commit 2751d463918b201f36afd1356408272f544816ab) --- pom.xml | 8 ++ .../nio/SocketChannelFrameHandlerFactory.java | 16 +++- .../client/impl/nio/SslEngineHelper.java | 9 +- .../test/ssl/NioTlsUnverifiedConnection.java | 89 ++++++++++++++++--- 4 files changed, 101 insertions(+), 21 deletions(-) diff --git a/pom.xml b/pom.xml index dae3fc505c..038648aea8 100644 --- a/pom.xml +++ b/pom.xml @@ -64,6 +64,7 @@ 3.22.0 9.4.44.v20210927 1.70 + 0.10 3.2.0 2.5.3 @@ -759,6 +760,13 @@ ${bouncycastle.version} test + + com.github.netcrusherorg + netcrusher-core + ${netcrusher.version} + test + + diff --git a/src/main/java/com/rabbitmq/client/impl/nio/SocketChannelFrameHandlerFactory.java b/src/main/java/com/rabbitmq/client/impl/nio/SocketChannelFrameHandlerFactory.java index 10f550d70a..5e5b9016d1 100644 --- a/src/main/java/com/rabbitmq/client/impl/nio/SocketChannelFrameHandlerFactory.java +++ b/src/main/java/com/rabbitmq/client/impl/nio/SocketChannelFrameHandlerFactory.java @@ -1,4 +1,4 @@ -// Copyright (c) 2007-2020 VMware, Inc. or its affiliates. All rights reserved. +// Copyright (c) 2007-2022 VMware, Inc. or its affiliates. All rights reserved. // // This software, the RabbitMQ Java client library, is triple-licensed under the // Mozilla Public License 2.0 ("MPL"), the GNU General Public License version 2 @@ -21,6 +21,9 @@ import com.rabbitmq.client.impl.AbstractFrameHandlerFactory; import com.rabbitmq.client.impl.FrameHandler; import com.rabbitmq.client.impl.TlsUtils; +import java.nio.channels.Channels; +import java.nio.channels.ReadableByteChannel; +import java.nio.channels.WritableByteChannel; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -95,14 +98,23 @@ public FrameHandler create(Address addr, String connectionName) throws IOExcepti channel.connect(address); + if (ssl) { + int initialSoTimeout = channel.socket().getSoTimeout(); + channel.socket().setSoTimeout(this.connectionTimeout); sslEngine.beginHandshake(); try { - boolean handshake = SslEngineHelper.doHandshake(channel, sslEngine); + ReadableByteChannel wrappedReadChannel = Channels.newChannel( + channel.socket().getInputStream()); + WritableByteChannel wrappedWriteChannel = Channels.newChannel( + channel.socket().getOutputStream()); + boolean handshake = SslEngineHelper.doHandshake( + wrappedWriteChannel, wrappedReadChannel, sslEngine); if (!handshake) { LOGGER.error("TLS connection failed"); throw new SSLException("TLS handshake failed"); } + channel.socket().setSoTimeout(initialSoTimeout); } catch (SSLHandshakeException e) { LOGGER.error("TLS connection failed: {}", e.getMessage()); throw e; diff --git a/src/main/java/com/rabbitmq/client/impl/nio/SslEngineHelper.java b/src/main/java/com/rabbitmq/client/impl/nio/SslEngineHelper.java index bcefe8b205..b7a535da87 100644 --- a/src/main/java/com/rabbitmq/client/impl/nio/SslEngineHelper.java +++ b/src/main/java/com/rabbitmq/client/impl/nio/SslEngineHelper.java @@ -1,4 +1,4 @@ -// Copyright (c) 2007-2021 VMware, Inc. or its affiliates. All rights reserved. +// Copyright (c) 2007-2022 VMware, Inc. or its affiliates. All rights reserved. // // This software, the RabbitMQ Java client library, is triple-licensed under the // Mozilla Public License 2.0 ("MPL"), the GNU General Public License version 2 @@ -21,7 +21,6 @@ import java.io.IOException; import java.nio.ByteBuffer; import java.nio.channels.ReadableByteChannel; -import java.nio.channels.SocketChannel; import java.nio.channels.WritableByteChannel; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -38,7 +37,7 @@ public class SslEngineHelper { private static final Logger LOGGER = LoggerFactory.getLogger(SslEngineHelper.class); - public static boolean doHandshake(SocketChannel socketChannel, SSLEngine engine) throws IOException { + public static boolean doHandshake(WritableByteChannel writeChannel, ReadableByteChannel readChannel, SSLEngine engine) throws IOException { ByteBuffer plainOut = ByteBuffer.allocate(engine.getSession().getApplicationBufferSize()); ByteBuffer plainIn = ByteBuffer.allocate(engine.getSession().getApplicationBufferSize()); @@ -58,11 +57,11 @@ public static boolean doHandshake(SocketChannel socketChannel, SSLEngine engine) break; case NEED_UNWRAP: LOGGER.debug("Unwrapping..."); - handshakeStatus = unwrap(cipherIn, plainIn, socketChannel, engine); + handshakeStatus = unwrap(cipherIn, plainIn, readChannel, engine); break; case NEED_WRAP: LOGGER.debug("Wrapping..."); - handshakeStatus = wrap(plainOut, cipherOut, socketChannel, engine); + handshakeStatus = wrap(plainOut, cipherOut, writeChannel, engine); break; case FINISHED: break; diff --git a/src/test/java/com/rabbitmq/client/test/ssl/NioTlsUnverifiedConnection.java b/src/test/java/com/rabbitmq/client/test/ssl/NioTlsUnverifiedConnection.java index 132cac31cc..4010bc444e 100644 --- a/src/test/java/com/rabbitmq/client/test/ssl/NioTlsUnverifiedConnection.java +++ b/src/test/java/com/rabbitmq/client/test/ssl/NioTlsUnverifiedConnection.java @@ -1,4 +1,4 @@ -// Copyright (c) 2007-2021 VMware, Inc. or its affiliates. All rights reserved. +// Copyright (c) 2007-2022 VMware, Inc. or its affiliates. All rights reserved. // // This software, the RabbitMQ Java client library, is triple-licensed under the // Mozilla Public License 2.0 ("MPL"), the GNU General Public License version 2 @@ -15,31 +15,39 @@ package com.rabbitmq.client.test.ssl; -import com.rabbitmq.client.*; +import static com.rabbitmq.client.test.TestUtils.basicGetBasicConsume; +import static org.assertj.core.api.Assertions.assertThat; +import static org.junit.Assert.assertTrue; +import static org.junit.Assert.fail; + +import com.rabbitmq.client.Connection; +import com.rabbitmq.client.ConnectionFactory; +import com.rabbitmq.client.TrustEverythingTrustManager; import com.rabbitmq.client.impl.nio.NioParams; import com.rabbitmq.client.test.BrokerTestCase; import com.rabbitmq.client.test.TestUtils; +import java.io.IOException; +import java.net.InetSocketAddress; +import java.net.SocketTimeoutException; import java.util.Collection; +import java.util.concurrent.CountDownLatch; +import java.util.concurrent.ExecutorService; +import java.util.concurrent.Executors; +import java.util.concurrent.TimeUnit; +import java.util.concurrent.TimeoutException; +import java.util.concurrent.atomic.AtomicBoolean; import java.util.concurrent.atomic.AtomicReference; import java.util.stream.Collectors; import java.util.stream.Stream; import javax.net.ssl.SSLContext; +import javax.net.ssl.SSLEngine; import javax.net.ssl.TrustManager; import org.junit.Test; +import org.netcrusher.core.reactor.NioReactor; +import org.netcrusher.tcp.TcpCrusher; +import org.netcrusher.tcp.TcpCrusherBuilder; import org.slf4j.LoggerFactory; -import javax.net.ssl.SSLEngine; -import java.io.IOException; -import java.util.concurrent.CountDownLatch; -import java.util.concurrent.TimeUnit; -import java.util.concurrent.TimeoutException; -import java.util.concurrent.atomic.AtomicBoolean; - -import static com.rabbitmq.client.test.TestUtils.basicGetBasicConsume; -import static org.assertj.core.api.Assertions.assertThat; -import static org.junit.Assert.assertTrue; -import static org.junit.Assert.fail; - /** * */ @@ -149,6 +157,59 @@ public void connectionGetConsumeProtocols() throws Exception { } } + @Test + public void connectionShouldEnforceConnectionTimeout() throws Exception { + int amqpPort = 5671; // assumes RabbitMQ server running on localhost; + int amqpProxyPort = TestUtils.randomNetworkPort(); + + int connectionTimeout = 3_000; + int handshakeTimeout = 1_000; + + try (NioReactor reactor = new NioReactor(); + TcpCrusher tcpProxy = + TcpCrusherBuilder.builder() + .withReactor(reactor) + .withBindAddress(new InetSocketAddress(amqpProxyPort)) + .withConnectAddress("localhost", amqpPort) + .build()) { + + tcpProxy.open(); + tcpProxy.freeze(); + + ConnectionFactory factory = new ConnectionFactory(); + factory.setHost("localhost"); + factory.setPort(amqpProxyPort); + + factory.useSslProtocol(); + factory.useNio(); + + factory.setConnectionTimeout(connectionTimeout); + factory.setHandshakeTimeout(handshakeTimeout); + + ExecutorService executorService = Executors.newSingleThreadExecutor(); + try { + CountDownLatch latch = new CountDownLatch(1); + executorService.submit( + () -> { + try { + factory.newConnection(); + latch.countDown(); + } catch (SocketTimeoutException e) { + latch.countDown(); + } catch (Exception e) { + // not supposed to happen + } + }); + + boolean connectionCreatedTimedOut = latch.await(10, TimeUnit.SECONDS); + assertThat(connectionCreatedTimedOut).isTrue(); + + } finally { + executorService.shutdownNow(); + } + } + } + private void sendAndVerifyMessage(int size) throws Exception { CountDownLatch latch = new CountDownLatch(1); boolean messageReceived = basicGetBasicConsume(connection, QUEUE, latch, size); From fcb9bf84fb759af478a3d74cd213787ed595bdc4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Arnaud=20Cogolu=C3=A8gnes?= Date: Wed, 12 Jan 2022 17:03:48 +0100 Subject: [PATCH 046/151] Set timeout on NIO connection Fixes #720 (cherry picked from commit 510389efde7a206dc29e6de70ca4e01764ac4c68) --- .../client/impl/nio/SocketChannelFrameHandlerFactory.java | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/src/main/java/com/rabbitmq/client/impl/nio/SocketChannelFrameHandlerFactory.java b/src/main/java/com/rabbitmq/client/impl/nio/SocketChannelFrameHandlerFactory.java index 5e5b9016d1..a482ace825 100644 --- a/src/main/java/com/rabbitmq/client/impl/nio/SocketChannelFrameHandlerFactory.java +++ b/src/main/java/com/rabbitmq/client/impl/nio/SocketChannelFrameHandlerFactory.java @@ -58,12 +58,11 @@ public class SocketChannelFrameHandlerFactory extends AbstractFrameHandlerFactor private final List nioLoopContexts; - public SocketChannelFrameHandlerFactory(int connectionTimeout, NioParams nioParams, boolean ssl, SslContextFactory sslContextFactory) - throws IOException { + public SocketChannelFrameHandlerFactory(int connectionTimeout, NioParams nioParams, boolean ssl, SslContextFactory sslContextFactory) { super(connectionTimeout, null, ssl); this.nioParams = new NioParams(nioParams); this.sslContextFactory = sslContextFactory; - this.nioLoopContexts = new ArrayList(this.nioParams.getNbIoThreads()); + this.nioLoopContexts = new ArrayList<>(this.nioParams.getNbIoThreads()); for (int i = 0; i < this.nioParams.getNbIoThreads(); i++) { this.nioLoopContexts.add(new NioLoopContext(this, this.nioParams)); } @@ -96,7 +95,7 @@ public FrameHandler create(Address addr, String connectionName) throws IOExcepti nioParams.getSocketChannelConfigurator().configure(channel); } - channel.connect(address); + channel.socket().connect(address, this.connectionTimeout); if (ssl) { From 19948ded2b9f3942e63b9d0528384d757e62f368 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Arnaud=20Cogolu=C3=A8gnes?= Date: Thu, 13 Jan 2022 14:52:24 +0100 Subject: [PATCH 047/151] Bump dependencies References #717 (cherry picked from commit 42c4d613c0111a7500b769d04905a5c35773d953) --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index 038648aea8..5b030eda5c 100644 --- a/pom.xml +++ b/pom.xml @@ -56,7 +56,7 @@ 1.7.32 4.2.7 - 1.8.1 + 1.8.2 2.13.1 1.2.10 4.13.2 From 1dc6640cbe69214880aab0b782bb3ba7674afc06 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Arnaud=20Cogolu=C3=A8gnes?= Date: Thu, 3 Feb 2022 10:43:53 +0100 Subject: [PATCH 048/151] Use publish confirms in visibility effect test The test started to fail on a 2-node 3.10 cluster while it was OK before. The test expected messages to be almost immediately available in the queues after publishing, which is not realistic, as publishing is asynchronous. This commit enables publish confirms and waits for the confirms to arrive before purging and checking the content of the queues, which is more realistic in terms of expectations. The bulk of the test remains asynchronous in case it would hang like it used to do sometimes. (cherry picked from commit 24fd5953bf81de43066d72a149c73b70b6c02edc) --- .../server/EffectVisibilityCrossNodeTest.java | 43 ++++++++++++++++--- 1 file changed, 37 insertions(+), 6 deletions(-) diff --git a/src/test/java/com/rabbitmq/client/test/server/EffectVisibilityCrossNodeTest.java b/src/test/java/com/rabbitmq/client/test/server/EffectVisibilityCrossNodeTest.java index b4c9a0bc6a..0070d38c73 100644 --- a/src/test/java/com/rabbitmq/client/test/server/EffectVisibilityCrossNodeTest.java +++ b/src/test/java/com/rabbitmq/client/test/server/EffectVisibilityCrossNodeTest.java @@ -15,11 +15,15 @@ package com.rabbitmq.client.test.server; +import static org.assertj.core.api.Assertions.assertThat; import static org.junit.Assert.assertEquals; import java.io.IOException; +import java.util.Iterator; +import java.util.Set; import java.util.concurrent.*; +import java.util.concurrent.atomic.AtomicReference; import org.junit.Test; import com.rabbitmq.client.test.functional.ClusteredTestBase; @@ -31,16 +35,20 @@ public class EffectVisibilityCrossNodeTest extends ClusteredTestBase { private final String[] queues = new String[QUEUES]; + ExecutorService executorService; + @Override protected void createResources() throws IOException { for (int i = 0; i < queues.length ; i++) { queues[i] = alternateChannel.queueDeclare("", false, false, true, null).getQueue(); alternateChannel.queueBind(queues[i], "amq.fanout", ""); } + executorService = Executors.newSingleThreadExecutor(); } @Override protected void releaseResources() throws IOException { + executorService.shutdownNow(); for (int i = 0; i < queues.length ; i++) { alternateChannel.queueDelete(queues[i]); } @@ -53,14 +61,41 @@ protected void releaseResources() throws IOException { private static final byte[] msg = "".getBytes(); @Test public void effectVisibility() throws Exception { - ExecutorService executorService = Executors.newSingleThreadExecutor(); - try { + AtomicReference confirmLatch = new AtomicReference<>(); + Set publishIds = ConcurrentHashMap.newKeySet(); + channel.addConfirmListener( + (deliveryTag, multiple) -> { + if (multiple) { + Iterator iterator = publishIds.iterator(); + while (iterator.hasNext()) { + long publishId = iterator.next(); + if (publishId <= deliveryTag) { + iterator.remove(); + } + } + } else { + publishIds.remove(deliveryTag); + } + if (publishIds.isEmpty()) { + confirmLatch.get().countDown(); + } + }, + (deliveryTag, multiple) -> {}); + // the test bulk is asynchronous because this test has a history of hanging Future task = executorService.submit(() -> { + // we use publish confirm to make sure messages made it to the queues + // before checking their content + channel.confirmSelect(); for (int i = 0; i < BATCHES; i++) { Thread.sleep(10); // to avoid flow control for the connection + confirmLatch.set(new CountDownLatch(1)); for (int j = 0; j < MESSAGES_PER_BATCH; j++) { + long publishId = channel.getNextPublishSeqNo(); channel.basicPublish("amq.fanout", "", null, msg); + publishIds.add(publishId); } + assertThat(confirmLatch.get().await(10, TimeUnit.SECONDS)).isTrue(); + publishIds.clear(); for (int j = 0; j < queues.length; j++) { assertEquals(MESSAGES_PER_BATCH, channel.queuePurge(queues[j]).getMessageCount()); } @@ -68,9 +103,5 @@ protected void releaseResources() throws IOException { return null; }); task.get(1, TimeUnit.MINUTES); - } finally { - executorService.shutdownNow(); - executorService.awaitTermination(1, TimeUnit.SECONDS); - } } } From 2f1cab3a2c4eec553739db862ec3aef59382863f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Arnaud=20Cogolu=C3=A8gnes?= Date: Thu, 3 Feb 2022 11:30:47 +0100 Subject: [PATCH 049/151] Report unconfirmed messages in test (cherry picked from commit e237496c8eb08965d54b3c25d3866cdaedf31a16) --- .../client/test/server/EffectVisibilityCrossNodeTest.java | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/src/test/java/com/rabbitmq/client/test/server/EffectVisibilityCrossNodeTest.java b/src/test/java/com/rabbitmq/client/test/server/EffectVisibilityCrossNodeTest.java index 0070d38c73..17ac78e5d2 100644 --- a/src/test/java/com/rabbitmq/client/test/server/EffectVisibilityCrossNodeTest.java +++ b/src/test/java/com/rabbitmq/client/test/server/EffectVisibilityCrossNodeTest.java @@ -24,6 +24,7 @@ import java.util.concurrent.*; import java.util.concurrent.atomic.AtomicReference; +import org.junit.Assert; import org.junit.Test; import com.rabbitmq.client.test.functional.ClusteredTestBase; @@ -94,7 +95,10 @@ protected void releaseResources() throws IOException { channel.basicPublish("amq.fanout", "", null, msg); publishIds.add(publishId); } - assertThat(confirmLatch.get().await(10, TimeUnit.SECONDS)).isTrue(); + boolean confirmed = confirmLatch.get().await(10, TimeUnit.SECONDS); + if (!confirmed) { + Assert.fail("Messages not confirmed in 10 seconds: " + publishIds); + } publishIds.clear(); for (int j = 0; j < queues.length; j++) { assertEquals(MESSAGES_PER_BATCH, channel.queuePurge(queues[j]).getMessageCount()); From ad936582838e7934802abf2d89676147c1d14c83 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Arnaud=20Cogolu=C3=A8gnes?= Date: Thu, 3 Feb 2022 14:29:59 +0100 Subject: [PATCH 050/151] Register publish ID before sending message (cherry picked from commit 34b2f30a4bf6dac9cc3c24af752bd3de54aa4ce6) --- .../client/test/server/EffectVisibilityCrossNodeTest.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/test/java/com/rabbitmq/client/test/server/EffectVisibilityCrossNodeTest.java b/src/test/java/com/rabbitmq/client/test/server/EffectVisibilityCrossNodeTest.java index 17ac78e5d2..2a8dbe1df3 100644 --- a/src/test/java/com/rabbitmq/client/test/server/EffectVisibilityCrossNodeTest.java +++ b/src/test/java/com/rabbitmq/client/test/server/EffectVisibilityCrossNodeTest.java @@ -92,8 +92,8 @@ protected void releaseResources() throws IOException { confirmLatch.set(new CountDownLatch(1)); for (int j = 0; j < MESSAGES_PER_BATCH; j++) { long publishId = channel.getNextPublishSeqNo(); - channel.basicPublish("amq.fanout", "", null, msg); publishIds.add(publishId); + channel.basicPublish("amq.fanout", "", null, msg); } boolean confirmed = confirmLatch.get().await(10, TimeUnit.SECONDS); if (!confirmed) { From f9a6253f86f9893b836097f3d40b470e636e2a8c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Arnaud=20Cogolu=C3=A8gnes?= Date: Thu, 3 Feb 2022 14:52:20 +0100 Subject: [PATCH 051/151] Retry until queue is fully purged The test remains flaky even with publish confirms. Purging the queue repeatedly until all published messages have been purged serves the same purpose of eventual visibility. (cherry picked from commit faeed579f4ecbed0664f10dbed04c774f8687aeb) --- .../server/EffectVisibilityCrossNodeTest.java | 69 +++++++------------ 1 file changed, 24 insertions(+), 45 deletions(-) diff --git a/src/test/java/com/rabbitmq/client/test/server/EffectVisibilityCrossNodeTest.java b/src/test/java/com/rabbitmq/client/test/server/EffectVisibilityCrossNodeTest.java index 2a8dbe1df3..bf3c56bf58 100644 --- a/src/test/java/com/rabbitmq/client/test/server/EffectVisibilityCrossNodeTest.java +++ b/src/test/java/com/rabbitmq/client/test/server/EffectVisibilityCrossNodeTest.java @@ -15,16 +15,11 @@ package com.rabbitmq.client.test.server; -import static org.assertj.core.api.Assertions.assertThat; import static org.junit.Assert.assertEquals; import java.io.IOException; -import java.util.Iterator; -import java.util.Set; import java.util.concurrent.*; -import java.util.concurrent.atomic.AtomicReference; -import org.junit.Assert; import org.junit.Test; import com.rabbitmq.client.test.functional.ClusteredTestBase; @@ -62,49 +57,33 @@ protected void releaseResources() throws IOException { private static final byte[] msg = "".getBytes(); @Test public void effectVisibility() throws Exception { - AtomicReference confirmLatch = new AtomicReference<>(); - Set publishIds = ConcurrentHashMap.newKeySet(); - channel.addConfirmListener( - (deliveryTag, multiple) -> { - if (multiple) { - Iterator iterator = publishIds.iterator(); - while (iterator.hasNext()) { - long publishId = iterator.next(); - if (publishId <= deliveryTag) { - iterator.remove(); - } - } - } else { - publishIds.remove(deliveryTag); - } - if (publishIds.isEmpty()) { - confirmLatch.get().countDown(); + // the test bulk is asynchronous because this test has a history of hanging + Future task = + executorService.submit( + () -> { + for (int i = 0; i < BATCHES; i++) { + Thread.sleep(10); // to avoid flow control for the connection + for (int j = 0; j < MESSAGES_PER_BATCH; j++) { + channel.basicPublish("amq.fanout", "", null, msg); } - }, - (deliveryTag, multiple) -> {}); - // the test bulk is asynchronous because this test has a history of hanging - Future task = executorService.submit(() -> { - // we use publish confirm to make sure messages made it to the queues - // before checking their content - channel.confirmSelect(); - for (int i = 0; i < BATCHES; i++) { - Thread.sleep(10); // to avoid flow control for the connection - confirmLatch.set(new CountDownLatch(1)); - for (int j = 0; j < MESSAGES_PER_BATCH; j++) { - long publishId = channel.getNextPublishSeqNo(); - publishIds.add(publishId); - channel.basicPublish("amq.fanout", "", null, msg); - } - boolean confirmed = confirmLatch.get().await(10, TimeUnit.SECONDS); - if (!confirmed) { - Assert.fail("Messages not confirmed in 10 seconds: " + publishIds); - } - publishIds.clear(); - for (int j = 0; j < queues.length; j++) { - assertEquals(MESSAGES_PER_BATCH, channel.queuePurge(queues[j]).getMessageCount()); + for (int j = 0; j < queues.length; j++) { + String queue = queues[j]; + long timeout = 10 * 1000; + long waited = 0; + int purged = 0; + while (waited < timeout) { + purged += channel.queuePurge(queue).getMessageCount(); + if (purged == MESSAGES_PER_BATCH) { + break; } + Thread.sleep(10); + waited += 10; + } + assertEquals("Queue " + queue + " should have been purged after 10 seconds", + MESSAGES_PER_BATCH, purged); } - return null; + } + return null; }); task.get(1, TimeUnit.MINUTES); } From 1e96924fe0f01a75d11f0f5f763a7b38ccab95d5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Arnaud=20Cogolu=C3=A8gnes?= Date: Fri, 4 Feb 2022 09:05:36 +0100 Subject: [PATCH 052/151] Log test execution start and end CI jobs hang regularly, this could help to tell whether the cause is the tests themselves or something in the CI environment. (cherry picked from commit 8d9f1ff8ce115cf719b571a10281403870e7966d) --- src/test/resources/logback-test.xml | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/test/resources/logback-test.xml b/src/test/resources/logback-test.xml index ee88f442c2..596182704c 100644 --- a/src/test/resources/logback-test.xml +++ b/src/test/resources/logback-test.xml @@ -5,6 +5,8 @@ + + From dddf081c84f7cab594057bf2bba29e9cefa4ea89 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Arnaud=20Cogolu=C3=A8gnes?= Date: Mon, 7 Feb 2022 11:18:22 +0100 Subject: [PATCH 053/151] Add logging to topic permissions test Test tends to hang on CI. (cherry picked from commit f2e5a24bf078bfb3d95cc68dee221080bca7704f) --- .../client/test/server/TopicPermissions.java | 15 +++++++++++++++ src/test/resources/logback-test.xml | 1 + 2 files changed, 16 insertions(+) diff --git a/src/test/java/com/rabbitmq/client/test/server/TopicPermissions.java b/src/test/java/com/rabbitmq/client/test/server/TopicPermissions.java index 5b79de1387..323b9cba65 100644 --- a/src/test/java/com/rabbitmq/client/test/server/TopicPermissions.java +++ b/src/test/java/com/rabbitmq/client/test/server/TopicPermissions.java @@ -25,36 +25,45 @@ import java.io.IOException; import java.util.concurrent.Callable; import java.util.concurrent.TimeoutException; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; import static org.junit.Assert.fail; public class TopicPermissions extends BrokerTestCase { + private static final Logger LOGGER = LoggerFactory.getLogger(TopicPermissions.class); + String protectedTopic = "protected.topic"; String notProtectedTopic = "not.protected.topic"; String noneTopicExchange = "not.a.topic"; @Override protected boolean shouldRun() throws IOException { + LOGGER.debug("Checking if test should run"); return Host.isRabbitMqCtlCommandAvailable("set_topic_permissions"); } @Override protected void createResources() throws IOException, TimeoutException { + LOGGER.debug("Creating AMQP resources"); channel.exchangeDeclare(protectedTopic, BuiltinExchangeType.TOPIC); channel.exchangeDeclare(notProtectedTopic, BuiltinExchangeType.TOPIC); channel.exchangeDeclare(noneTopicExchange, BuiltinExchangeType.DIRECT); + LOGGER.debug("Setting permissions"); Host.rabbitmqctl("set_topic_permissions -p / guest " + protectedTopic + " \"^{username}\" \"^{username}\""); Host.rabbitmqctl("set_topic_permissions -p / guest " + noneTopicExchange + " \"^{username}\" \"^{username}\""); } @Override protected void releaseResources() throws IOException { + LOGGER.debug("Deleting AMQP resources"); channel.exchangeDelete(protectedTopic); channel.exchangeDelete(notProtectedTopic); channel.exchangeDelete(noneTopicExchange); + LOGGER.debug("Clearing permissions"); Host.rabbitmqctl("clear_topic_permissions -p / guest"); } @@ -107,14 +116,18 @@ public void topicPermissions() throws IOException { } void assertAccessOk(String description, Callable action) { + LOGGER.debug("Running '" + description + "'"); try { action.call(); } catch(Exception e) { fail(description + " (" + e.getMessage()+")"); + } finally { + LOGGER.debug("'" + description + "' done"); } } void assertAccessRefused(String description, Callable action) throws IOException { + LOGGER.debug("Running '" + description + "'"); try { action.call(); fail(description); @@ -126,6 +139,8 @@ void assertAccessRefused(String description, Callable action) throws IOExc openChannel(); } catch(Exception e) { fail("Unexpected exception: " + e.getMessage()); + } finally { + LOGGER.debug("'" + description + "' done"); } } } diff --git a/src/test/resources/logback-test.xml b/src/test/resources/logback-test.xml index 596182704c..90ebf5307e 100644 --- a/src/test/resources/logback-test.xml +++ b/src/test/resources/logback-test.xml @@ -6,6 +6,7 @@ + From b78e803d41a231b891b4ade5fdff53abd54a643b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Arnaud=20Cogolu=C3=A8gnes?= Date: Mon, 7 Feb 2022 12:04:20 +0100 Subject: [PATCH 054/151] Handle process better in Host The method to check if a command exists asks for the help of this command now (instead of checking if the command name is in the output of rabbitmqctl). This way we just have to check the exit code (0 if the command exists). We also use a timeout to wait for the end of the process. A test hangs on the CI environment, these changes try to fix this. (cherry picked from commit 6b2251fe05684f39eca99eb846179df4c0d91e7e) --- src/test/java/com/rabbitmq/tools/Host.java | 22 +++++++++++++++++----- 1 file changed, 17 insertions(+), 5 deletions(-) diff --git a/src/test/java/com/rabbitmq/tools/Host.java b/src/test/java/com/rabbitmq/tools/Host.java index e81aef9a93..74be79b66c 100644 --- a/src/test/java/com/rabbitmq/tools/Host.java +++ b/src/test/java/com/rabbitmq/tools/Host.java @@ -1,4 +1,4 @@ -// Copyright (c) 2007-2020 VMware, Inc. or its affiliates. All rights reserved. +// Copyright (c) 2007-2022 VMware, Inc. or its affiliates. All rights reserved. // // This software, the RabbitMQ Java client library, is triple-licensed under the // Mozilla Public License 2.0 ("MPL"), the GNU General Public License version 2 @@ -28,12 +28,17 @@ import com.rabbitmq.client.ConnectionFactory; import com.rabbitmq.client.impl.NetworkConnection; import com.rabbitmq.client.test.TestUtils; +import java.util.concurrent.TimeUnit; import java.util.function.Predicate; import java.util.regex.Matcher; import java.util.regex.Pattern; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; public class Host { + private static final Logger LOGGER = LoggerFactory.getLogger(Host.class); + private static final String DOCKER_PREFIX = "DOCKER:"; private static final Pattern CONNECTION_NAME_PATTERN = Pattern.compile("\"connection_name\",\"(?[a-zA-Z0-9\\-]+)?\""); @@ -78,7 +83,14 @@ private static int waitForExitValue(Process pr) { public static Process executeCommandIgnoringErrors(String command) throws IOException { Process pr = executeCommandProcess(command); - waitForExitValue(pr); + boolean exited = false; + try { + exited = pr.waitFor(30, TimeUnit.SECONDS); + } catch (InterruptedException e) { + } + if (!exited) { + LOGGER.warn("Command '{}' did not finish in 30 seconds", command); + } return pr; } @@ -101,9 +113,9 @@ private static Process executeCommandProcess(String command) throws IOException } public static boolean isRabbitMqCtlCommandAvailable(String command) throws IOException { - Process process = rabbitmqctlIgnoreErrors(""); - String stderr = capture(process.getErrorStream()); - return stderr.contains(command); + Process process = rabbitmqctlIgnoreErrors(command + " --help"); + int exitValue = process.exitValue(); + return exitValue == 0; } public static Process rabbitmqctl(String command) throws IOException { From 8da31a37673c6058e16bcc7f4bb00dee9278cc6a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Arnaud=20Cogolu=C3=A8gnes?= Date: Mon, 7 Feb 2022 14:30:53 +0100 Subject: [PATCH 055/151] Pump process inputs before checking completion Process completion methods can hang because internal buffers are full. This commit "pumps" the inputs before calling the completion method, which should help to finish properly the command call. (cherry picked from commit 17afacafdb58c37d987a5ad1eb1457c9ffbb7824) --- src/test/java/com/rabbitmq/tools/Host.java | 69 ++++++++++++++++++---- 1 file changed, 58 insertions(+), 11 deletions(-) diff --git a/src/test/java/com/rabbitmq/tools/Host.java b/src/test/java/com/rabbitmq/tools/Host.java index 74be79b66c..ee3b6a59f3 100644 --- a/src/test/java/com/rabbitmq/tools/Host.java +++ b/src/test/java/com/rabbitmq/tools/Host.java @@ -54,25 +54,68 @@ public static String capture(InputStream is) return buff.toString(); } - public static Process executeCommand(String command) throws IOException + public static ProcessState executeCommand(String command) throws IOException { Process pr = executeCommandProcess(command); + InputStreamPumpState inputState = new InputStreamPumpState(pr.getInputStream()); + InputStreamPumpState errorState = new InputStreamPumpState(pr.getErrorStream()); - int ev = waitForExitValue(pr); + int ev = waitForExitValue(pr, inputState, errorState); + inputState.pump(); + errorState.pump(); if (ev != 0) { - String stdout = capture(pr.getInputStream()); - String stderr = capture(pr.getErrorStream()); throw new IOException("unexpected command exit value: " + ev + "\ncommand: " + command + "\n" + - "\nstdout:\n" + stdout + - "\nstderr:\n" + stderr + "\n"); + "\nstdout:\n" + inputState.buffer.toString() + + "\nstderr:\n" + errorState.buffer.toString() + "\n"); } - return pr; + return new ProcessState(pr, inputState, errorState); + } + + static class ProcessState { + + private final Process process; + private final InputStreamPumpState inputState; + private final InputStreamPumpState errorState; + + ProcessState(Process process, InputStreamPumpState inputState, + InputStreamPumpState errorState) { + this.process = process; + this.inputState = inputState; + this.errorState = errorState; + } + + private String output() { + return inputState.buffer.toString(); + } + + } + + private static class InputStreamPumpState { + + private final BufferedReader reader; + private final StringBuilder buffer; + + private InputStreamPumpState(InputStream in) { + this.reader = new BufferedReader(new InputStreamReader(in)); + this.buffer = new StringBuilder(); + } + + void pump() throws IOException { + String line; + while ((line = reader.readLine()) != null) { + buffer.append(line).append("\n"); + } + } + } - private static int waitForExitValue(Process pr) { + private static int waitForExitValue(Process pr, InputStreamPumpState inputState, + InputStreamPumpState errorState) throws IOException { while(true) { try { + inputState.pump(); + errorState.pump(); pr.waitFor(); break; } catch (InterruptedException ignored) {} @@ -83,6 +126,10 @@ private static int waitForExitValue(Process pr) { public static Process executeCommandIgnoringErrors(String command) throws IOException { Process pr = executeCommandProcess(command); + InputStreamPumpState inputState = new InputStreamPumpState(pr.getInputStream()); + InputStreamPumpState errorState = new InputStreamPumpState(pr.getErrorStream()); + inputState.pump(); + errorState.pump(); boolean exited = false; try { exited = pr.waitFor(30, TimeUnit.SECONDS); @@ -118,7 +165,7 @@ public static boolean isRabbitMqCtlCommandAvailable(String command) throws IOExc return exitValue == 0; } - public static Process rabbitmqctl(String command) throws IOException { + public static ProcessState rabbitmqctl(String command) throws IOException { return executeCommand(rabbitmqctlCommand() + rabbitmqctlNodenameArgument() + " " + command); @@ -142,7 +189,7 @@ public static void clearResourceAlarm(String source) throws IOException { rabbitmqctl("eval 'rabbit_alarm:clear_alarm({resource_limit, " + source + ", node()}).'"); } - public static Process invokeMakeTarget(String command) throws IOException { + public static ProcessState invokeMakeTarget(String command) throws IOException { File rabbitmqctl = new File(rabbitmqctlCommand()); return executeCommand(makeCommand() + " -C \'" + rabbitmqDir() + "\'" + @@ -307,7 +354,7 @@ public String toString() { } public static List listConnections() throws IOException { - String output = capture(rabbitmqctl("list_connections -q pid peer_port client_properties").getInputStream()); + String output = rabbitmqctl("list_connections -q pid peer_port client_properties").output(); // output (header line presence depends on broker version): // pid peer_port // 58713 From b53e5ca2bf8abdf6967be3b79b3c85e2736b32da Mon Sep 17 00:00:00 2001 From: Laurent Perez Date: Wed, 9 Feb 2022 15:14:19 +0100 Subject: [PATCH 056/151] topology : fix connection factory property evaluation (cherry picked from commit ed7a83aa1abe584025383f43ec6625b9cffa9cb3) --- .../java/com/rabbitmq/client/ConnectionFactoryConfigurator.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main/java/com/rabbitmq/client/ConnectionFactoryConfigurator.java b/src/main/java/com/rabbitmq/client/ConnectionFactoryConfigurator.java index d59770380e..66f4a3742d 100644 --- a/src/main/java/com/rabbitmq/client/ConnectionFactoryConfigurator.java +++ b/src/main/java/com/rabbitmq/client/ConnectionFactoryConfigurator.java @@ -210,7 +210,7 @@ public static void load(ConnectionFactory cf, Map properties, St } String topologyRecovery = lookUp(TOPOLOGY_RECOVERY_ENABLED, properties, prefix); if (topologyRecovery != null) { - cf.setTopologyRecoveryEnabled(Boolean.getBoolean(topologyRecovery)); + cf.setTopologyRecoveryEnabled(Boolean.valueOf(topologyRecovery)); } String networkRecoveryInterval = lookUp(CONNECTION_RECOVERY_INTERVAL, properties, prefix); if (networkRecoveryInterval != null) { From 7e6c46c9462204dba54ce7a93f5ed3d87bece338 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Arnaud=20Cogolu=C3=A8gnes?= Date: Wed, 16 Feb 2022 09:24:57 +0100 Subject: [PATCH 057/151] Bump dependencies References #717 (cherry picked from commit b613dc1f277de28de63caa6cd6e5bcdf2a0c0c10) --- pom.xml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/pom.xml b/pom.xml index 5b030eda5c..27120dacd5 100644 --- a/pom.xml +++ b/pom.xml @@ -54,8 +54,8 @@ UTF-8 UTF-8 - 1.7.32 - 4.2.7 + 1.7.36 + 4.2.8 1.8.2 2.13.1 1.2.10 From ba9c54849bb26d645299eab6a4ecc93d1fb876f7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Arnaud=20Cogolu=C3=A8gnes?= Date: Wed, 16 Feb 2022 09:25:57 +0100 Subject: [PATCH 058/151] Bump test dependencies (cherry picked from commit 99c4e738b037a00b9eb1878847f4cc75e1188ccb) --- pom.xml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/pom.xml b/pom.xml index 27120dacd5..78534eb35b 100644 --- a/pom.xml +++ b/pom.xml @@ -60,9 +60,9 @@ 2.13.1 1.2.10 4.13.2 - 4.2.0 + 4.3.1 3.22.0 - 9.4.44.v20210927 + 9.4.45.v20220203 1.70 0.10 From 7e38ec9597ecd550f902a9201f6b03b065f6d7a1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Arnaud=20Cogolu=C3=A8gnes?= Date: Mon, 21 Feb 2022 10:26:59 +0100 Subject: [PATCH 059/151] Add log before starting each test CI environment hangs sometimes, this should help diagnose if a test in particular is hanging. (cherry picked from commit 02fba0c106c6f3fe4ff6d4ec505a27c09bc78aca) --- .../com/rabbitmq/client/test/ClientTests.java | 4 +- .../client/test/RequiredPropertiesSuite.java | 11 +++++ .../com/rabbitmq/client/test/TestUtils.java | 46 ++++++++++++++++++- .../test/functional/FunctionalTests.java | 2 +- .../rabbitmq/client/test/ssl/SSLTests.java | 15 +++++- src/test/resources/logback-test.xml | 3 ++ 6 files changed, 75 insertions(+), 6 deletions(-) diff --git a/src/test/java/com/rabbitmq/client/test/ClientTests.java b/src/test/java/com/rabbitmq/client/test/ClientTests.java index 681542ab70..b8550640ca 100644 --- a/src/test/java/com/rabbitmq/client/test/ClientTests.java +++ b/src/test/java/com/rabbitmq/client/test/ClientTests.java @@ -1,4 +1,4 @@ -// Copyright (c) 2007-2020 VMware, Inc. or its affiliates. All rights reserved. +// Copyright (c) 2007-2022 VMware, Inc. or its affiliates. All rights reserved. // // This software, the RabbitMQ Java client library, is triple-licensed under the // Mozilla Public License 2.0 ("MPL"), the GNU General Public License version 2 @@ -27,7 +27,7 @@ import org.junit.runner.RunWith; import org.junit.runners.Suite; -@RunWith(Suite.class) +@RunWith(TestUtils.DefaultTestSuite.class) @Suite.SuiteClasses({ TableTest.class, LongStringTest.class, diff --git a/src/test/java/com/rabbitmq/client/test/RequiredPropertiesSuite.java b/src/test/java/com/rabbitmq/client/test/RequiredPropertiesSuite.java index b97a0b0af6..f8ab431800 100644 --- a/src/test/java/com/rabbitmq/client/test/RequiredPropertiesSuite.java +++ b/src/test/java/com/rabbitmq/client/test/RequiredPropertiesSuite.java @@ -1,18 +1,23 @@ package com.rabbitmq.client.test; import org.junit.runner.Runner; +import org.junit.runner.notification.RunNotifier; import org.junit.runners.Suite; import org.junit.runners.model.InitializationError; import org.junit.runners.model.RunnerBuilder; import java.util.ArrayList; import java.util.List; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; /** * */ public class RequiredPropertiesSuite extends Suite { + private static final Logger LOGGER = LoggerFactory.getLogger(RequiredPropertiesSuite.class); + public RequiredPropertiesSuite(Class klass, RunnerBuilder builder) throws InitializationError { super(klass, builder); } @@ -41,4 +46,10 @@ protected List getChildren() { return super.getChildren(); } } + + @Override + protected void runChild(Runner runner, RunNotifier notifier) { + LOGGER.info("Running test {}", runner.getDescription().getDisplayName()); + super.runChild(runner, notifier); + } } diff --git a/src/test/java/com/rabbitmq/client/test/TestUtils.java b/src/test/java/com/rabbitmq/client/test/TestUtils.java index c488fcff6d..0c0ea49a89 100644 --- a/src/test/java/com/rabbitmq/client/test/TestUtils.java +++ b/src/test/java/com/rabbitmq/client/test/TestUtils.java @@ -1,4 +1,4 @@ -// Copyright (c) 2007-2021 VMware, Inc. or its affiliates. All rights reserved. +// Copyright (c) 2007-2022 VMware, Inc. or its affiliates. All rights reserved. // // This software, the RabbitMQ Java client library, is triple-licensed under the // Mozilla Public License 2.0 ("MPL"), the GNU General Public License version 2 @@ -19,11 +19,18 @@ import com.rabbitmq.client.impl.NetworkConnection; import com.rabbitmq.client.impl.recovery.AutorecoveringConnection; import com.rabbitmq.tools.Host; +import java.util.List; import org.assertj.core.api.Assertions; import org.junit.AssumptionViolatedException; import org.junit.rules.TestRule; import org.junit.runner.Description; +import org.junit.runner.Runner; +import org.junit.runner.notification.RunNotifier; +import org.junit.runners.Suite; +import org.junit.runners.model.InitializationError; +import org.junit.runners.model.RunnerBuilder; import org.junit.runners.model.Statement; +import org.slf4j.Logger; import org.slf4j.LoggerFactory; import java.io.IOException; @@ -40,6 +47,8 @@ public class TestUtils { + private static final Logger LOGGER = LoggerFactory.getLogger(TestUtils.class); + public static final boolean USE_NIO = System.getProperty("use.nio") != null; public static ConnectionFactory connectionFactory() { @@ -364,4 +373,39 @@ public void handleDelivery(String consumerTag, Envelope envelope, AMQP.BasicProp return messageReceived; } + + public static class DefaultTestSuite extends Suite { + + + public DefaultTestSuite(Class klass, RunnerBuilder builder) + throws InitializationError { + super(klass, builder); + } + + public DefaultTestSuite(RunnerBuilder builder, Class[] classes) + throws InitializationError { + super(builder, classes); + } + + protected DefaultTestSuite(Class klass, Class[] suiteClasses) + throws InitializationError { + super(klass, suiteClasses); + } + + protected DefaultTestSuite(RunnerBuilder builder, Class klass, Class[] suiteClasses) + throws InitializationError { + super(builder, klass, suiteClasses); + } + + @Override + protected void runChild(Runner runner, RunNotifier notifier) { + LOGGER.info("Running test {}", runner.getDescription().getDisplayName()); + super.runChild(runner, notifier); + } + + protected DefaultTestSuite(Class klass, List runners) + throws InitializationError { + super(klass, runners); + } + } } diff --git a/src/test/java/com/rabbitmq/client/test/functional/FunctionalTests.java b/src/test/java/com/rabbitmq/client/test/functional/FunctionalTests.java index db87a38695..892f4977ba 100644 --- a/src/test/java/com/rabbitmq/client/test/functional/FunctionalTests.java +++ b/src/test/java/com/rabbitmq/client/test/functional/FunctionalTests.java @@ -1,4 +1,4 @@ -// Copyright (c) 2007-2020 VMware, Inc. or its affiliates. All rights reserved. +// Copyright (c) 2007-2022 VMware, Inc. or its affiliates. All rights reserved. // // This software, the RabbitMQ Java client library, is triple-licensed under the // Mozilla Public License 2.0 ("MPL"), the GNU General Public License version 2 diff --git a/src/test/java/com/rabbitmq/client/test/ssl/SSLTests.java b/src/test/java/com/rabbitmq/client/test/ssl/SSLTests.java index 3d629d15ea..758d87118a 100644 --- a/src/test/java/com/rabbitmq/client/test/ssl/SSLTests.java +++ b/src/test/java/com/rabbitmq/client/test/ssl/SSLTests.java @@ -1,4 +1,4 @@ -// Copyright (c) 2007-2020 VMware, Inc. or its affiliates. All rights reserved. +// Copyright (c) 2007-2022 VMware, Inc. or its affiliates. All rights reserved. // // This software, the RabbitMQ Java client library, is triple-licensed under the // Mozilla Public License 2.0 ("MPL"), the GNU General Public License version 2 @@ -20,12 +20,15 @@ import com.rabbitmq.client.test.SslContextFactoryTest; import org.junit.runner.RunWith; import org.junit.runner.Runner; +import org.junit.runner.notification.RunNotifier; import org.junit.runners.Suite; import org.junit.runners.model.InitializationError; import org.junit.runners.model.RunnerBuilder; import java.util.ArrayList; import java.util.List; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; @RunWith(SSLTests.SslSuite.class) @Suite.SuiteClasses({ @@ -40,6 +43,8 @@ }) public class SSLTests { + private static final Logger LOGGER = LoggerFactory.getLogger(SSLTests.class); + // initialize system properties static{ new AbstractRMQTestSuite(){}; @@ -70,11 +75,17 @@ protected SslSuite(Class klass, List runners) throws InitializationEr @Override protected List getChildren() { if(!AbstractRMQTestSuite.requiredProperties() && !AbstractRMQTestSuite.isSSLAvailable()) { - return new ArrayList(); + return new ArrayList<>(); } else { return super.getChildren(); } } + + @Override + protected void runChild(Runner runner, RunNotifier notifier) { + LOGGER.info("Running test {}", runner.getDescription().getDisplayName()); + super.runChild(runner, notifier); + } } } diff --git a/src/test/resources/logback-test.xml b/src/test/resources/logback-test.xml index 90ebf5307e..5874c1c8c4 100644 --- a/src/test/resources/logback-test.xml +++ b/src/test/resources/logback-test.xml @@ -5,6 +5,9 @@ + + + From 04b060dbb28b61ff70af522403be3ad1d9e3d3c2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Arnaud=20Cogolu=C3=A8gnes?= Date: Fri, 25 Feb 2022 16:24:33 +0100 Subject: [PATCH 060/151] Copy element-list to package-list in Javadoc deployment For Java8-generated Javadoc to link correctly to the library Javadoc whatever Java version used to generate it. See https://bugs.openjdk.java.net/browse/JDK-8211194. (cherry picked from commit 04bc4caed4a89b9da8e8815d1771e00ed189a79d) --- deploy-javadoc.sh | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/deploy-javadoc.sh b/deploy-javadoc.sh index 74878215e9..46cdb09398 100755 --- a/deploy-javadoc.sh +++ b/deploy-javadoc.sh @@ -5,6 +5,11 @@ TAG=$(git describe --exact-match --tags $(git log -n1 --pretty='%h')) make deps ./mvnw -q clean javadoc:javadoc -Dmaven.javadoc.failOnError=false + +if [ -e target/site/apidocs/element-list ] + then cp target/site/apidocs/element-list target/site/apidocs/package-list +fi + git co gh-pages rm -rf $DEPLOY_DIRECTORY/* cp -r target/site/apidocs/* $DEPLOY_DIRECTORY From 896fc56d6c61e6ffa23be27648a6971b67b48fad Mon Sep 17 00:00:00 2001 From: David Ansari Date: Sun, 27 Feb 2022 15:19:59 +0100 Subject: [PATCH 061/151] Add tests for any-with-x and all-with-x for x-match binding argument in headers exchange (cherry picked from commit 7e92c2df240f326c4afff3eb803cf1efeda65f9f) --- .../functional/HeadersExchangeValidation.java | 6 +++ .../client/test/functional/Routing.java | 45 +++++++++++++++++++ 2 files changed, 51 insertions(+) diff --git a/src/test/java/com/rabbitmq/client/test/functional/HeadersExchangeValidation.java b/src/test/java/com/rabbitmq/client/test/functional/HeadersExchangeValidation.java index b2eeee7719..e62dd04d0b 100644 --- a/src/test/java/com/rabbitmq/client/test/functional/HeadersExchangeValidation.java +++ b/src/test/java/com/rabbitmq/client/test/functional/HeadersExchangeValidation.java @@ -47,6 +47,12 @@ public class HeadersExchangeValidation extends BrokerTestCase { arguments.put("x-match", "any"); succeedBind(queue, arguments); + + arguments.put("x-match", "all-with-x"); + succeedBind(queue, arguments); + + arguments.put("x-match", "any-with-x"); + succeedBind(queue, arguments); } private void failBind(String queue, HashMap arguments) { diff --git a/src/test/java/com/rabbitmq/client/test/functional/Routing.java b/src/test/java/com/rabbitmq/client/test/functional/Routing.java index 050eb379b0..45161acddc 100644 --- a/src/test/java/com/rabbitmq/client/test/functional/Routing.java +++ b/src/test/java/com/rabbitmq/client/test/functional/Routing.java @@ -170,6 +170,7 @@ private void checkGet(String queue, boolean messageExpected) spec.put("h1", "12345"); spec.put("h2", "bar"); spec.put("h3", null); + spec.put("x-key-1", "bindings starting with x- get filtered out"); spec.put("x-match", "all"); channel.queueBind(Q1, "amq.match", "", spec); spec.put("x-match", "any"); @@ -226,6 +227,10 @@ private void checkGet(String queue, boolean messageExpected) map.put("h2", "quux"); channel.basicPublish("amq.match", "", props.build(), "8".getBytes()); + map.clear(); + map.put("x-key-1", "bindings starting with x- get filtered out"); + channel.basicPublish("amq.match", "", props.build(), "9".getBytes()); + checkGet(Q1, true); // 4 checkGet(Q1, false); @@ -240,6 +245,46 @@ private void checkGet(String queue, boolean messageExpected) checkGet(Q2, false); } + @Test public void headersWithXRouting() throws Exception { + Map spec = new HashMap(); + spec.put("x-key-1", "value-1"); + spec.put("x-key-2", "value-2"); + spec.put("x-match", "all-with-x"); + channel.queueBind(Q1, "amq.match", "", spec); + spec.put("x-match", "any-with-x"); + channel.queueBind(Q2, "amq.match", "", spec); + + AMQP.BasicProperties.Builder props = new AMQP.BasicProperties.Builder(); + channel.basicPublish("amq.match", "", props.build(), "0".getBytes()); + + Map map = new HashMap(); + props.headers(map); + + map.clear(); + map.put("x-key-1", "value-1"); + channel.basicPublish("amq.match", "", props.build(), "1".getBytes()); + + map.clear(); + map.put("x-key-1", "value-1"); + map.put("x-key-2", "value-2"); + channel.basicPublish("amq.match", "", props.build(), "2".getBytes()); + + map.clear(); + map.put("x-key-1", "value-1"); + map.put("x-key-2", "value-2"); + map.put("x-key-3", "value-3"); + channel.basicPublish("amq.match", "", props.build(), "3".getBytes()); + + checkGet(Q1, true); // 2 + checkGet(Q1, true); // 3 + checkGet(Q1, false); + + checkGet(Q2, true); // 1 + checkGet(Q2, true); // 2 + checkGet(Q2, true); // 3 + checkGet(Q2, false); + } + @Test public void basicReturn() throws IOException { channel.addReturnListener(makeReturnListener()); returnCell = new BlockingCell(); From f5cf5cb0e6075b3bfc4005f89788a85d4f66118b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Arnaud=20Cogolu=C3=A8gnes?= Date: Mon, 28 Feb 2022 09:57:24 +0100 Subject: [PATCH 062/151] Add test condition to test x-match=all-with-x Broker version >= 3.10. References #725 (cherry picked from commit 0b7d8f0b778aa1bbd7eb13e517abf84b2782fafe) --- .../com/rabbitmq/client/test/TestUtils.java | 57 +++++++++++++++++++ .../functional/HeadersExchangeValidation.java | 13 +++-- .../client/test/functional/Routing.java | 13 ++++- 3 files changed, 76 insertions(+), 7 deletions(-) diff --git a/src/test/java/com/rabbitmq/client/test/TestUtils.java b/src/test/java/com/rabbitmq/client/test/TestUtils.java index 0c0ea49a89..86605d71f9 100644 --- a/src/test/java/com/rabbitmq/client/test/TestUtils.java +++ b/src/test/java/com/rabbitmq/client/test/TestUtils.java @@ -19,6 +19,11 @@ import com.rabbitmq.client.impl.NetworkConnection; import com.rabbitmq.client.impl.recovery.AutorecoveringConnection; import com.rabbitmq.tools.Host; +import java.lang.annotation.ElementType; +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; +import java.lang.annotation.Target; +import java.lang.reflect.Method; import java.util.List; import org.assertj.core.api.Assertions; import org.junit.AssumptionViolatedException; @@ -130,6 +135,10 @@ public static boolean isVersion38orLater(Connection connection) { return atLeastVersion("3.8.0", connection); } + public static boolean isVersion310orLater(Connection connection) { + return atLeastVersion("3.10.0", connection); + } + private static boolean atLeastVersion(String expectedVersion, Connection connection) { String currentVersion = null; try { @@ -408,4 +417,52 @@ protected DefaultTestSuite(Class klass, List runners) super(klass, runners); } } + + @Target({ElementType.METHOD}) + @Retention(RetentionPolicy.RUNTIME) + public @interface TestExecutionCondition { + + Class[] value(); + + } + + interface ExecutionCondition { + + void check(Description description) throws Exception; + + } + + public static class BrokerAtLeast310Condition implements ExecutionCondition { + + private static final String VERSION = "3.10.0"; + + @Override + public void check(Description description) throws Exception { + try (Connection c = TestUtils.connectionFactory().newConnection()) { + if (!TestUtils.atLeastVersion(VERSION, c)) { + throw new AssumptionViolatedException("Broker version < " + VERSION + ", skipping."); + } + } + } + } + + public static class ExecutionConditionRule implements TestRule { + + @Override + public Statement apply(Statement base, Description description) { + return new Statement() { + @Override + public void evaluate() throws Throwable { + Method testMethod = description.getTestClass().getDeclaredMethod(description.getMethodName()); + TestExecutionCondition conditionAnnotation = testMethod.getAnnotation( + TestExecutionCondition.class); + if (conditionAnnotation != null) { + conditionAnnotation.value()[0].getConstructor().newInstance() + .check(description); + } + base.evaluate(); + } + }; + } + } } diff --git a/src/test/java/com/rabbitmq/client/test/functional/HeadersExchangeValidation.java b/src/test/java/com/rabbitmq/client/test/functional/HeadersExchangeValidation.java index e62dd04d0b..c82ed749b6 100644 --- a/src/test/java/com/rabbitmq/client/test/functional/HeadersExchangeValidation.java +++ b/src/test/java/com/rabbitmq/client/test/functional/HeadersExchangeValidation.java @@ -1,4 +1,4 @@ -// Copyright (c) 2007-2020 VMware, Inc. or its affiliates. All rights reserved. +// Copyright (c) 2007-2022 VMware, Inc. or its affiliates. All rights reserved. // // This software, the RabbitMQ Java client library, is triple-licensed under the // Mozilla Public License 2.0 ("MPL"), the GNU General Public License version 2 @@ -17,6 +17,7 @@ import static org.junit.Assert.fail; +import com.rabbitmq.client.test.TestUtils; import java.io.IOException; import java.util.HashMap; @@ -48,11 +49,13 @@ public class HeadersExchangeValidation extends BrokerTestCase { arguments.put("x-match", "any"); succeedBind(queue, arguments); - arguments.put("x-match", "all-with-x"); - succeedBind(queue, arguments); + if (TestUtils.isVersion310orLater(connection)) { + arguments.put("x-match", "all-with-x"); + succeedBind(queue, arguments); - arguments.put("x-match", "any-with-x"); - succeedBind(queue, arguments); + arguments.put("x-match", "any-with-x"); + succeedBind(queue, arguments); + } } private void failBind(String queue, HashMap arguments) { diff --git a/src/test/java/com/rabbitmq/client/test/functional/Routing.java b/src/test/java/com/rabbitmq/client/test/functional/Routing.java index 45161acddc..30a643a918 100644 --- a/src/test/java/com/rabbitmq/client/test/functional/Routing.java +++ b/src/test/java/com/rabbitmq/client/test/functional/Routing.java @@ -1,4 +1,4 @@ -// Copyright (c) 2007-2020 VMware, Inc. or its affiliates. All rights reserved. +// Copyright (c) 2007-2022 VMware, Inc. or its affiliates. All rights reserved. // // This software, the RabbitMQ Java client library, is triple-licensed under the // Mozilla Public License 2.0 ("MPL"), the GNU General Public License version 2 @@ -21,6 +21,9 @@ import static org.junit.Assert.assertNull; import static org.junit.Assert.fail; +import com.rabbitmq.client.test.TestUtils.BrokerAtLeast310Condition; +import com.rabbitmq.client.test.TestUtils.ExecutionConditionRule; +import com.rabbitmq.client.test.TestUtils.TestExecutionCondition; import java.io.IOException; import java.util.ArrayList; import java.util.HashMap; @@ -28,6 +31,7 @@ import java.util.Map; import java.util.concurrent.TimeoutException; +import org.junit.Rule; import org.junit.Test; import com.rabbitmq.client.AMQP; @@ -36,10 +40,13 @@ import com.rabbitmq.client.ReturnListener; import com.rabbitmq.client.test.BrokerTestCase; import com.rabbitmq.utility.BlockingCell; +import org.junit.rules.TestRule; public class Routing extends BrokerTestCase { + @Rule public TestRule executionConditionRule = new ExecutionConditionRule(); + protected final String E = "MRDQ"; protected final String Q1 = "foo"; protected final String Q2 = "bar"; @@ -245,7 +252,9 @@ private void checkGet(String queue, boolean messageExpected) checkGet(Q2, false); } - @Test public void headersWithXRouting() throws Exception { + @Test + @TestExecutionCondition(BrokerAtLeast310Condition.class) + public void headersWithXRouting() throws Exception { Map spec = new HashMap(); spec.put("x-key-1", "value-1"); spec.put("x-key-2", "value-2"); From b8ecfaf96aa88e9643530dae8ecd9511134529f8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Arnaud=20Cogolu=C3=A8gnes?= Date: Fri, 11 Mar 2022 11:38:17 +0100 Subject: [PATCH 063/151] Set -Dmaven.wagon.http.retryHandler.count=10 in .mvn/maven.config Trying to help download dependencing from CI. (cherry picked from commit 80440298e3179c28fcb1c4a398bd95b1858ce42b) --- .mvn/maven.config | 1 + 1 file changed, 1 insertion(+) create mode 100644 .mvn/maven.config diff --git a/.mvn/maven.config b/.mvn/maven.config new file mode 100644 index 0000000000..f373d1de10 --- /dev/null +++ b/.mvn/maven.config @@ -0,0 +1 @@ +-Dmaven.wagon.http.retryHandler.count=10 From c1735cafa0b7a4bae9547b5a7d8e5443f09b07ea Mon Sep 17 00:00:00 2001 From: Michael Klishin Date: Fri, 11 Mar 2022 18:50:23 +0400 Subject: [PATCH 064/151] Wording (cherry picked from commit 0c933cb2c659e014df60e07352f163ecbae1641a) Conflicts: src/main/java/com/rabbitmq/client/impl/AMQConnection.java --- src/main/java/com/rabbitmq/client/impl/AMQConnection.java | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/main/java/com/rabbitmq/client/impl/AMQConnection.java b/src/main/java/com/rabbitmq/client/impl/AMQConnection.java index 2592345baa..61b7a678a9 100644 --- a/src/main/java/com/rabbitmq/client/impl/AMQConnection.java +++ b/src/main/java/com/rabbitmq/client/impl/AMQConnection.java @@ -750,8 +750,8 @@ private void readFrame(Frame frame) throws IOException { /** private API */ public void handleHeartbeatFailure() { - Exception ex = new MissedHeartbeatException("Heartbeat missing with heartbeat = " + - _heartbeat + " seconds"); + Exception ex = new MissedHeartbeatException("Detected missed server heartbeats, heartbeat interval: " + + _heartbeat + " seconds, RabbitMQ node hostname: " + this.getHostAddress()); try { _exceptionHandler.handleUnexpectedConnectionDriverException(this, ex); shutdown(null, false, ex, true); From 659c21fdcc3e7d5f16e84468c6a184beaac8da16 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Arnaud=20Cogolu=C3=A8gnes?= Date: Wed, 30 Mar 2022 15:15:13 +0200 Subject: [PATCH 065/151] Use available processor number for default thread count in consumer work service The current value is available processors times 2, which may be overkill nowadays. The commit also allows using the rabbitmq.amqp.client.availableProcessors system property value, which is convenient as it's configuration-based (no code changes required). Fixes #730 (cherry picked from commit 49c5e2cf5c55bf0a775550004a7e168eeea6d413) --- .../client/impl/ConsumerWorkService.java | 15 ++++++--- .../java/com/rabbitmq/client/impl/Utils.java | 31 +++++++++++++++++++ 2 files changed, 42 insertions(+), 4 deletions(-) create mode 100644 src/main/java/com/rabbitmq/client/impl/Utils.java diff --git a/src/main/java/com/rabbitmq/client/impl/ConsumerWorkService.java b/src/main/java/com/rabbitmq/client/impl/ConsumerWorkService.java index b3810aae2f..f607e816e3 100644 --- a/src/main/java/com/rabbitmq/client/impl/ConsumerWorkService.java +++ b/src/main/java/com/rabbitmq/client/impl/ConsumerWorkService.java @@ -1,4 +1,4 @@ -// Copyright (c) 2007-2020 VMware, Inc. or its affiliates. All rights reserved. +// Copyright (c) 2007-2022 VMware, Inc. or its affiliates. All rights reserved. // // This software, the RabbitMQ Java client library, is triple-licensed under the // Mozilla Public License 2.0 ("MPL"), the GNU General Public License version 2 @@ -22,10 +22,13 @@ import java.util.concurrent.ThreadFactory; import com.rabbitmq.client.Channel; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; final public class ConsumerWorkService { + private static final Logger LOGGER = LoggerFactory.getLogger(ConsumerWorkService.class); private static final int MAX_RUNNABLE_BLOCK_SIZE = 16; - private static final int DEFAULT_NUM_THREADS = Runtime.getRuntime().availableProcessors() * 2; + private static final int DEFAULT_NUM_THREADS = Math.max(1, Utils.availableProcessors()); private final ExecutorService executor; private final boolean privateExecutor; private final WorkPool workPool; @@ -33,8 +36,12 @@ final public class ConsumerWorkService { public ConsumerWorkService(ExecutorService executor, ThreadFactory threadFactory, int queueingTimeout, int shutdownTimeout) { this.privateExecutor = (executor == null); - this.executor = (executor == null) ? Executors.newFixedThreadPool(DEFAULT_NUM_THREADS, threadFactory) - : executor; + if (executor == null) { + LOGGER.debug("Creating executor service with {} thread(s) for consumer work service", DEFAULT_NUM_THREADS); + this.executor = Executors.newFixedThreadPool(DEFAULT_NUM_THREADS, threadFactory); + } else { + this.executor = executor; + } this.workPool = new WorkPool<>(queueingTimeout); this.shutdownTimeout = shutdownTimeout; } diff --git a/src/main/java/com/rabbitmq/client/impl/Utils.java b/src/main/java/com/rabbitmq/client/impl/Utils.java new file mode 100644 index 0000000000..d3e3412ee4 --- /dev/null +++ b/src/main/java/com/rabbitmq/client/impl/Utils.java @@ -0,0 +1,31 @@ +// Copyright (c) 2022 VMware, Inc. or its affiliates. All rights reserved. +// +// This software, the RabbitMQ Java client library, is triple-licensed under the +// Mozilla Public License 2.0 ("MPL"), the GNU General Public License version 2 +// ("GPL") and the Apache License version 2 ("ASL"). For the MPL, please see +// LICENSE-MPL-RabbitMQ. For the GPL, please see LICENSE-GPL2. For the ASL, +// please see LICENSE-APACHE2. +// +// This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY KIND, +// either express or implied. See the LICENSE file for specific language governing +// rights and limitations of this software. +// +// If you have any questions regarding licensing, please contact us at +// info@rabbitmq.com. + +package com.rabbitmq.client.impl; + +final class Utils { + + private static final int AVAILABLE_PROCESSORS = + Integer.parseInt( + System.getProperty( + "rabbitmq.amqp.client.availableProcessors", + String.valueOf(Runtime.getRuntime().availableProcessors()))); + + static int availableProcessors() { + return AVAILABLE_PROCESSORS; + } + + private Utils() {} +} From e2743af9d8a34bd87501a29076f5499a1ea1eb67 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Arnaud=20Cogolu=C3=A8gnes?= Date: Fri, 8 Apr 2022 14:44:28 +0200 Subject: [PATCH 066/151] Bump optional dependencies References #717 --- pom.xml | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/pom.xml b/pom.xml index 78534eb35b..a0bb91a56e 100644 --- a/pom.xml +++ b/pom.xml @@ -55,9 +55,9 @@ UTF-8 1.7.36 - 4.2.8 - 1.8.2 - 2.13.1 + 4.2.9 + 1.8.4 + 2.13.2.2 1.2.10 4.13.2 4.3.1 From 7d5099ed4b8327346c5e6d654e1d6c1211b342b4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Arnaud=20Cogolu=C3=A8gnes?= Date: Fri, 8 Apr 2022 14:46:01 +0200 Subject: [PATCH 067/151] Bump test dependencies --- pom.xml | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/pom.xml b/pom.xml index a0bb91a56e..7c08b5647e 100644 --- a/pom.xml +++ b/pom.xml @@ -58,11 +58,11 @@ 4.2.9 1.8.4 2.13.2.2 - 1.2.10 + 1.2.11 4.13.2 - 4.3.1 + 4.4.0 3.22.0 - 9.4.45.v20220203 + 9.4.46.v20220331 1.70 0.10 From 96f5b0e23433a1620505cb8ba655940bd8f99a36 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Arnaud=20Cogolu=C3=A8gnes?= Date: Fri, 8 Apr 2022 15:04:34 +0200 Subject: [PATCH 068/151] Bump plugins --- pom.xml | 26 +++++++++++++------------- 1 file changed, 13 insertions(+), 13 deletions(-) diff --git a/pom.xml b/pom.xml index 7c08b5647e..b9b63f8ca3 100644 --- a/pom.xml +++ b/pom.xml @@ -66,24 +66,24 @@ 1.70 0.10 - 3.2.0 + 3.3.2 2.5.3 - 2.3 - 3.1.0 - 3.0.1 + 2.10.0 + 3.2.0 + 3.2.1 2.1.1 - 2.4.8 + 2.4.21 1.5 - 1.12 - 3.8.1 + 3.3.0 + 3.10.1 2.22.2 2.22.2 - 1.6 - 3.0.2 - 3.2.0 + 3.0.1 + 3.2.2 + 5.1.4 0.0.6 - 1.6.8 - 1.8 + 1.6.12 + 1.11 1.3 - javadoc-no-module-dir-java-11 - - [11,) - - - --no-module-directories - - -

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy