Commit Graph

1316 Commits

Author SHA1 Message Date
Loïc Hoguin ed080e8a27
CQ shared: Fix off-by-nine error leading to lost messages
And `eof` crashes.

The problem is that we may end up trying to read more data
from the file when scanning, despite being at the end of the
file. This results in the current Acc to be returned instead
of the remaining data being parsed.

This results in some messages at the end of the file being
truncated off despite still being in memory (and still pointing
to the end of the original file, well past the truncation point).
2025-09-24 15:05:17 -04:00
Michal Kuratczyk dc3de1701d
rabbitmq-diagnostics message_size_stats
This command displays cluster-wide message size
statistics. It's less detailed than what can be
retrieved from the Prometheus endpoint, but
it'll be available to all users, regardless of their
monitoring setup, or lack thereof.
2025-09-24 15:05:17 -04:00
Arnaud Cogoluègnes 6238dac1c3
Adapt stream code to Osiris read ahead
Osiris can read ahead data in case of small chunks. This saves system
calls and increases consumption rate dramatically for some streams.
This is transparent for the stream protocol, but requires a small tweak
for the stream queue type implementation (passing in the previous
iterator when creating a new one).

The read ahead is on by default but can be deactivated with to the new
stream.read_ahead configuration entry (true / false).

Co-authored-by: Karl Nilsson <kjnilsson@gmail.com>

References rabbitmq/osiris#192
2025-09-24 15:05:16 -04:00
dependabot[bot] 77ba21b946
[skip ci] Bump the dev-deps group across 4 directories with 2 updates
Bumps the dev-deps group with 2 updates in the /deps/rabbit/test/amqp_jms_SUITE_data directory: org.apache.qpid:qpid-jms-client and [org.assertj:assertj-core](https://github.com/assertj/assertj).
Bumps the dev-deps group with 1 update in the /deps/rabbitmq_mqtt/test/java_SUITE_data directory: [org.assertj:assertj-core](https://github.com/assertj/assertj).
Bumps the dev-deps group with 1 update in the /deps/rabbitmq_stream/test/rabbit_stream_SUITE_data directory: [org.assertj:assertj-core](https://github.com/assertj/assertj).
Bumps the dev-deps group with 1 update in the /deps/rabbitmq_stream_management/test/http_SUITE_data directory: [org.assertj:assertj-core](https://github.com/assertj/assertj).


Updates `org.apache.qpid:qpid-jms-client` from 2.8.0 to 2.9.0

Updates `org.assertj:assertj-core` from 3.27.4 to 3.27.5
- [Release notes](https://github.com/assertj/assertj/releases)
- [Commits](https://github.com/assertj/assertj/compare/assertj-build-3.27.4...assertj-build-3.27.5)

Updates `org.assertj:assertj-core` from 3.27.4 to 3.27.5
- [Release notes](https://github.com/assertj/assertj/releases)
- [Commits](https://github.com/assertj/assertj/compare/assertj-build-3.27.4...assertj-build-3.27.5)

Updates `org.assertj:assertj-core` from 3.27.4 to 3.27.5
- [Release notes](https://github.com/assertj/assertj/releases)
- [Commits](https://github.com/assertj/assertj/compare/assertj-build-3.27.4...assertj-build-3.27.5)

Updates `org.assertj:assertj-core` from 3.27.4 to 3.27.5
- [Release notes](https://github.com/assertj/assertj/releases)
- [Commits](https://github.com/assertj/assertj/compare/assertj-build-3.27.4...assertj-build-3.27.5)

---
updated-dependencies:
- dependency-name: org.apache.qpid:qpid-jms-client
  dependency-version: 2.9.0
  dependency-type: direct:development
  update-type: version-update:semver-minor
  dependency-group: dev-deps
- dependency-name: org.assertj:assertj-core
  dependency-version: 3.27.5
  dependency-type: direct:development
  update-type: version-update:semver-patch
  dependency-group: dev-deps
- dependency-name: org.assertj:assertj-core
  dependency-version: 3.27.5
  dependency-type: direct:development
  update-type: version-update:semver-patch
  dependency-group: dev-deps
- dependency-name: org.assertj:assertj-core
  dependency-version: 3.27.5
  dependency-type: direct:development
  update-type: version-update:semver-patch
  dependency-group: dev-deps
- dependency-name: org.assertj:assertj-core
  dependency-version: 3.27.5
  dependency-type: direct:development
  update-type: version-update:semver-patch
  dependency-group: dev-deps
...

Signed-off-by: dependabot[bot] <support@github.com>
2025-09-24 15:05:16 -04:00
David Ansari e404d10eea
Speed up fanout exchange (#14546)
* Add test case for binding args Khepri regression

This commit adds a test case for a regression/bug that occurs in Khepri.
```
make -C deps/rabbit ct-bindings t=cluster:binding_args RABBITMQ_METADATA_STORE=mnesia
```
succeeds, but
```
make -C deps/rabbit ct-bindings t=cluster:binding_args RABBITMQ_METADATA_STORE=khepri
```
fails.

The problem is that ETS table `rabbit_khepri_index_route` cannot
differentiate between two bindings with different binding arguments, and
therefore deletes entries too early, leading to wrong routing decisions.

The solution to this bug is to include the binding arguments in the
`rabbit_khepri_index_route` projection, similar to how the binding args
are also included in the `rabbit_index_route` Mnesia table.

This bug/regression is an edge case and exists if the source exchange
type is `direct` or `fanout` and if different bindings arguments are
used by client apps. Note that such binding arguments are entirely
ignored when RabbitMQ performs routing decisions for the `direct` or
`fanout` exchange. However, there might be client apps that use binding
arguments to add some metadata to the binding, for example `app-id` or
`user` or `purpose` and might use this metadata as a form of reference
counting in deciding when to delete `auto-delete` exchanges or just for
informational/operational purposes.

* Fix regression with Khepri binding args

Fix #14533

* Speed up fanout exchange

Resolves #14531

 ## What?
Increase end-to-end message throughput for messages routed via the fanout exchange by ~42% (see benchmark below).
In addition to the fanout exchange, a similar speed up is achieved for the following exchange types:
* modulus hash
* random
* recent history

This applies only if Khepri is enabled.

 ## How?
Use an additional routing table (projection) whose table key is the source exchange.
Looking up the destinations happens then by an ETS table key.

Prior to this commit, CPUs were busy compiling the same match spec for every incoming message.

 ## Benchmark
1. Start RabbitMQ:
```
make run-broker RABBITMQ_SERVER_ADDITIONAL_ERL_ARGS="+S 5" \
    RABBITMQ_CONFIG_FILE="advanced.config" PLUGINS="rabbitmq_management"
```
where `advanced.config` contains:
```
[
 {rabbitmq_management_agent, [
  {disable_metrics_collector, true}
 ]}
].
```

2. Create a queue and binding:
```
deps/rabbitmq_management/bin/rabbitmqadmin declare queue queue_type=classic durable=true name=q1 && \
deps/rabbitmq_management/bin/rabbitmqadmin declare binding source=amq.fanout destination=q1
```

3. Create the load
```
java -jar target/perf-test.jar -p -e amq.fanout -u q1 -s 5 --autoack -z 60
```

Before this commit:
```
sending rate avg: 97394 msg/s
receiving rate avg: 97394 msg/s
```

After this commit:
```
sending rate avg: 138677 msg/s
receiving rate avg: 138677 msg/s
```

The CPU flamegraph shows that `rabbit_exchange:route/3` consumes the following CPU amounts:
* 13.5% before this commit
* 3.4% after this commit

 ## Downsides
Additional ETS memory usage for the new projection table.
However, the new table does not store any binding entries for the following
source exchange types:
* direct
* headers
* topic
* x-local-random

* Add exchange binding tests

Test that exchange bindings work correctly with the new projection
tables `rabbit_khepri_route_by_source` and
`rabbit_khepri_route_by_source_key`.

* Always register all projections

Khepri won’t modify a projection that is already registered (based on its name).

* Protect ets:lookup_element/4 in try catch

See https://github.com/rabbitmq/rabbitmq-server/pull/11667#issue-2401399413
for rationale.
2025-09-24 15:05:16 -04:00
dependabot[bot] 29c084f0c9
[skip ci] Bump the prod-deps group across 5 directories with 3 updates
Bumps the prod-deps group with 1 update in the /deps/rabbit/test/amqp_jms_SUITE_data directory: [org.apache.maven.plugins:maven-surefire-plugin](https://github.com/apache/maven-surefire).
Bumps the prod-deps group with 2 updates in the /deps/rabbitmq_auth_backend_http/examples/rabbitmq_auth_backend_spring_boot_kotlin directory: [org.jetbrains.kotlin:kotlin-test](https://github.com/JetBrains/kotlin) and org.jetbrains.kotlin:kotlin-maven-allopen.
Bumps the prod-deps group with 1 update in the /deps/rabbitmq_mqtt/test/java_SUITE_data directory: [org.apache.maven.plugins:maven-surefire-plugin](https://github.com/apache/maven-surefire).
Bumps the prod-deps group with 1 update in the /deps/rabbitmq_stream/test/rabbit_stream_SUITE_data directory: [org.apache.maven.plugins:maven-surefire-plugin](https://github.com/apache/maven-surefire).
Bumps the prod-deps group with 1 update in the /deps/rabbitmq_stream_management/test/http_SUITE_data directory: [org.apache.maven.plugins:maven-surefire-plugin](https://github.com/apache/maven-surefire).


Updates `org.apache.maven.plugins:maven-surefire-plugin` from 3.5.3 to 3.5.4
- [Release notes](https://github.com/apache/maven-surefire/releases)
- [Commits](https://github.com/apache/maven-surefire/compare/surefire-3.5.3...surefire-3.5.4)

Updates `org.jetbrains.kotlin:kotlin-test` from 2.2.10 to 2.2.20
- [Release notes](https://github.com/JetBrains/kotlin/releases)
- [Changelog](https://github.com/JetBrains/kotlin/blob/master/ChangeLog.md)
- [Commits](https://github.com/JetBrains/kotlin/compare/v2.2.10...v2.2.20)

Updates `org.jetbrains.kotlin:kotlin-maven-allopen` from 2.2.10 to 2.2.20

Updates `org.apache.maven.plugins:maven-surefire-plugin` from 3.5.3 to 3.5.4
- [Release notes](https://github.com/apache/maven-surefire/releases)
- [Commits](https://github.com/apache/maven-surefire/compare/surefire-3.5.3...surefire-3.5.4)

Updates `org.apache.maven.plugins:maven-surefire-plugin` from 3.5.3 to 3.5.4
- [Release notes](https://github.com/apache/maven-surefire/releases)
- [Commits](https://github.com/apache/maven-surefire/compare/surefire-3.5.3...surefire-3.5.4)

Updates `org.apache.maven.plugins:maven-surefire-plugin` from 3.5.3 to 3.5.4
- [Release notes](https://github.com/apache/maven-surefire/releases)
- [Commits](https://github.com/apache/maven-surefire/compare/surefire-3.5.3...surefire-3.5.4)

---
updated-dependencies:
- dependency-name: org.apache.maven.plugins:maven-surefire-plugin
  dependency-version: 3.5.4
  dependency-type: direct:production
  update-type: version-update:semver-patch
  dependency-group: prod-deps
- dependency-name: org.jetbrains.kotlin:kotlin-test
  dependency-version: 2.2.20
  dependency-type: direct:development
  update-type: version-update:semver-patch
  dependency-group: prod-deps
- dependency-name: org.jetbrains.kotlin:kotlin-maven-allopen
  dependency-version: 2.2.20
  dependency-type: direct:production
  update-type: version-update:semver-patch
  dependency-group: prod-deps
- dependency-name: org.apache.maven.plugins:maven-surefire-plugin
  dependency-version: 3.5.4
  dependency-type: direct:production
  update-type: version-update:semver-patch
  dependency-group: prod-deps
- dependency-name: org.apache.maven.plugins:maven-surefire-plugin
  dependency-version: 3.5.4
  dependency-type: direct:production
  update-type: version-update:semver-patch
  dependency-group: prod-deps
- dependency-name: org.apache.maven.plugins:maven-surefire-plugin
  dependency-version: 3.5.4
  dependency-type: direct:production
  update-type: version-update:semver-patch
  dependency-group: prod-deps
...

Signed-off-by: dependabot[bot] <support@github.com>
2025-09-13 18:11:55 +00:00
David Ansari 0843704dbb Disallow multiple consumers on one volatile queue
There can be at most one consumer per volatile queue instance.
This consumer must also have attached on the same channel/session as the
creator of the queue.

Prior to this commit, it was possible for clients on other
connections or sessions to attach a receiving link to an existing volatile
queue name, even though no messages would be delivered.

It's better for RabbitMQ to directly refuse the link at attach time.
2025-09-12 12:06:51 +02:00
David Ansari 72cd7a35c2 Support Direct Reply-To for AMQP 1.0
# What?
* Support Direct Reply-To for AMQP 1.0
* Compared to AMQP 0.9.1, this PR allows for multiple volatile queues on a single
  AMQP 1.0 session. Use case: JMS clients can create multiple temporary queues on
  the same JMS/AMQP session:
  * https://jakarta.ee/specifications/messaging/3.1/apidocs/jakarta.messaging/jakarta/jms/session#createTemporaryQueue()
  * https://jakarta.ee/specifications/messaging/3.1/apidocs/jakarta.messaging/jakarta/jms/jmscontext#createTemporaryQueue()
* Fix missing metrics in for Direct Reply-To in AMQP 0.9.1, e.g.
  `messages_delivered_total`
* Fix missing metrics (even without using Direct Reply-To ) in AMQP 0.9.1:
  If stats level is not `fine`, global metrics `rabbitmq_global_messages_delivered_*` should still be incremented.

 # Why?
* Allow for scalable at-most-once RPC reply delivery
  Example use case: thousands of requesters connect, send a single
  request, wait for a single reply, and disconnect.
  This PR won't create any queue and won't write to the metadata store.
  Therefore, there's less pressure on the metadata store, less pressure
  on the Management API when listing all queues, less pressure on the
  metrics subsystem, etc.
* Feature parity with AMQP 0.9.1

 # How?
This PR extracts the previously channel specific Direct Reply-To code
into a new queue type: `rabbit_volatile_queue`.
"Volatile" describes the semantics, not a use-case. It signals non-durable,
zero-buffer, at-most-once, may-drop, and "not stored in Khepri."

This new queue type is then used for AMQP 1.0 and AMQP 0.9.1.

Sending to the volatile queue is stateless like previously with Direct Reply-To in AMQP 0.9.1 and like done
for the MQTT QoS 0 queue.
This allows for use cases where a single responder replies to e.g. 100k different requesters.

RabbitMQ will automatically auto grant new link-credit to the responder because the new queue type confirms immediately.

The key gets implicitly checked by the channel/session:
If the queue name (including the key) doesn’t exist, the `handle_event` callback for this queue isn’t invoked and therefore
no delivery will be sent to the responder.

This commit supports Direct Reply-To across AMQP 1.0 and 0.9.1. In other
words, the requester can be an AMQP 1.0 client while the responder is an
AMQP 0.9.1 client or vice versa.
RabbitMQ will internally convert between AMQP 0.9.1 `reply_to` and AMQP
1.0 `/queues/<queue>` address. The AMQP 0.9.1 `reply_to` property is
expected to contain a queue name. That's in line with the AMQP 0.9.1
spec:
> One of the standard message properties is Reply-To, which is designed
specifically for carrying the name of reply queues.

Compared to AMQP 0.9.1 where the requester sets the `reply_to` property
to `amq.rabbitmq.reply-to` and RabbitMQ modifies this field when
forwarding the message to the request queue, in AMQP 1.0 the requester
learns about the queue name from the broker at link attachment time.
The requester has to set the reply-to property to the server generated
queue name. That's because the server isn't allowed to modify the bare
message.

During link attachment time, the client has to set certain fields.
These fields are expected to be set by the RabbitMQ client libraries.
Here is an Erlang example:
```erl
Source = #{address => undefined,
           durable => none,
           expiry_policy => <<"link-detach">>,
           dynamic => true,
           capabilities => [<<"rabbitmq:volatile-queue">>]},
AttachArgs = #{name => <<"receiver">>,
               role => {receiver, Source, self()},
               snd_settle_mode => settled,
               rcv_settle_mode => first},
{ok, Receiver} = amqp10_client:attach_link(Session, AttachArgs),
AddressReplyQ = receive {amqp10_event, {link, Receiver, {attached, Attach}}} ->
                  #'v1_0.attach'{source = #'v1_0.source'{address = {utf8, Addr}}} = Attach,
                  Addr
end,
```

The client then sends the message by setting the reply-to address as
follows:
```erl
amqp10_client:send_msg(
  SenderRequester,
  amqp10_msg:set_properties(
    #{message_id => <<"my ID">>,
      reply_to => AddressReplyQ},
    amqp10_msg:new(<<"tag">>, <<"request">>))),
```

If the responder attaches to the queue target in the reply-to field,
RabbitMQ will check if the requester link is still attached. If the
requester detached, the link will be refused.

The responder can also attach to the anonymous null target and set the
`to` field to the `reply-to` address.

If RabbitMQ cannot deliver a reply, instead of buffering the reply,
RabbitMQ will be drop the reply and increment the following Prometheus metric:
```
rabbitmq_global_messages_dead_lettered_maxlen_total{queue_type="rabbit_volatile_queue",dead_letter_strategy="disabled"} 0.0
```
That's in line with the MQTT QoS 0 queue type.

A reply message could be dropped for a variety of reasons:
1. The requester ran out of link-credit. It's therefore the requester's
   responsibility to grant sufficient link-credit on its receiving link.
2. RabbitMQ isn't allowed to deliver any message to due session flow
   control. It's the requster's responsibility to keep the session window
   large enough.
3. The requester doesn't consume messages fast enough causing TCP
   backpressure being applied or the RabbitMQ AMQP writer proc isn't
   scheduled quickly enough. The latter can happen for example if
   RabbitMQ runs with a single scheduler (is assigned a single CPU
   core). In either case, RabbitMQ internal flow control causes the
   volatile queue to drop messages.

Therefore, if high throughput is required while message loss is undesirable, a classic queue should be used
instead of a volatile queue since the former buffers messages while the
latter doesn't.

The main difference between the volatile queue and the MQTT QoS 0 queue
is that the former isn't written to the metadata store.

 # Breaking Change
Prior to this PR the following [documented caveat](https://www.rabbitmq.com/docs/4.0/direct-reply-to#limitations) applied:
> If the RPC server publishes with the mandatory flag set then `amq.rabbitmq.reply-to.*`
is treated as **not** a queue; i.e. if the server only publishes to this name then the message
will be considered "not routed"; a `basic.return` will be sent if the mandatory flag was set.

This PR removes this caveat.
This PR introduces the following new behaviour:
> If the RPC server publishes with the mandatory flag set, then `amq.rabbitmq.reply-to.*`
is treated as a queue (assuming this queue name is encoded correctly). However,
whether the requester is still there to consume the reply is not checked at routing time.
In other words, if the RPC server only publishes to this name, then the message will be
considered "routed" and RabbitMQ will therefore not send a `basic.return`.
2025-09-09 14:52:22 +02:00
David Ansari def157a105
Merge pull request #14438 from rabbitmq/stream-queue-leader-fix
Fix issue where leader is not returned after stream declaration
2025-09-01 15:32:22 +02:00
dependabot[bot] 225e3617d9
[skip ci] Bump org.apache.qpid:qpid-jms-client
Bumps the dev-deps group with 1 update in the /deps/rabbit/test/amqp_jms_SUITE_data directory: org.apache.qpid:qpid-jms-client.


Updates `org.apache.qpid:qpid-jms-client` from 2.7.0 to 2.8.0

---
updated-dependencies:
- dependency-name: org.apache.qpid:qpid-jms-client
  dependency-version: 2.8.0
  dependency-type: direct:development
  update-type: version-update:semver-minor
  dependency-group: dev-deps
...

Signed-off-by: dependabot[bot] <support@github.com>
2025-08-30 18:02:44 +00:00
Karl Nilsson e5891e24de Fix issue where leader is not returned after stream declaration
This would affect the meta data that is returned when declaring
a queue through AMQP.
2025-08-27 14:40:08 +01:00
David Ansari eef470df37 Detach link for link-level errors
## What?
Refuse or detach the link instead of ending the session for many
link-level errors, including the following:
* Source queue or target exchange doesn't exist during attach
* Trying to consume from an exclusive queue on a different connection
* Delivery of message to a target queue fails
* Wrong delivery-id
* Wrong settled flag
* Queue declaration fails for dynamic queues
* Publishing to internal exchange

 ## Why?
Because many errors are scoped to a single terminus, detaching just that link
preserves the rest of the session’s links - avoiding needless disruption of
other traffic. AMQP 1.0’s error model is hierarchical; RabbitMQ should escalate to
ending the session only for session-level faults or if the client keeps
using a destroyed link.

 ## How?
Refuse link as per figure 2.33
2025-08-27 09:49:22 +02:00
Jean-Sébastien Pédron 4f1c6f0bde
clustering_recovery_SUITE: Add `recover_after_partition_with_leader` testcase
[Why]
The testcase tries to replicate the steps described in issue #12934.

[How]
It uses intermediate Erlang nodes between the common_test control node
and the RabbitMQ nodes, using `peer` standard_io communication. The goal
is to make sure the common_test control node doesn't interfere with the
nodes the RabbitMQ nodes can see, despite the blocking of the Erlang
distribution connection.

So far, I couldn't reproduce the problem reported in #12934. @mkuratczyk
couldn't either, so it might have been fixed as a side effect of another
change...

References #12934.
2025-08-14 12:10:52 +02:00
Jean-Sébastien Pédron 23588b665a
rabbit_access_control: Check configured auth backends are enabled at boot time
[Why]
If a user configures an auth backend module, but doesn't enabled the
plugin that provides it, it will get a crash and a stacktrace when
authentication is performed. The error is not helpful to understand what
the problem is.

[How]
We add a boot step that go through the configured auth backends and
query the core of RabbitMQ and the plugins. If an auth backend is
provided by a plugin, the plugin must be enabled to consider the auth
backend to be valid.

In the end, at least one auth backend must be valid, otherwise the boot
is aborted.

If only some of the configured auth backends were filtered out, but
there are still some valid auth backends, we store the filtered list in
the application environment variable so that
authentication/authorization doesn't try to use them later.

We also report invalid auth backends in the logs:

* Info message for a single invalid auth backend:

    [info] <0.213.0> The `rabbit_auth_backend_ldap` auth backend module is configured. However, the `rabbitmq_auth_backend_ldap` plugin must be enabled in order to use this auth backend. Until then it will be skipped during authentication/authorization

* Warning message when some auth backends were filtered out:

    [warning] <0.213.0> Some configured backends were dropped because their corresponding plugins are disabled. Please look at the info messages above to learn which plugin(s) should be enabled. Here is the list of auth backends kept after filering:
    [warning] <0.213.0> [rabbit_auth_backend_internal]

* Error message when no auth backends are valid:

    [error] <0.213.0> None of the configured auth backends are usable because their corresponding plugins were not enabled. Please look at the info messages above to learn which plugin(s) should be enabled.

V2: In fact, `rabbit_plugins:is_enabled/1` indicates if a plugin is
    running, not if it is enabled... The new check runs as a boot step
    and thus is executed before plugins are started. Therefore we can't
    use this API. Instead, we use `rabbit_plugins:enabled_plugins/0'
    which lists explicitly enabled plugins. The drawback is that in the
    auth backend is enabled implicitly because it is a dependency of
    another explicitly enabled plugin, the check will still consider it
    is disabled and thus abort the boot.

Fixes #13783.
2025-08-12 18:38:28 +02:00
Michael Klishin 5f69116a64
Merge pull request #14364 from rabbitmq/mk-bump-cuttlefish
Cuttlefish 3.5.0
2025-08-11 14:15:13 -04:00
Michael Klishin 7413511195
Cuttlefish 3.5.0
This version forces prefixed binaries
(such as encrypted:TkQbjiVWtUJw3Ed/hkJ5JIsFIyhruKII6uKPXogfvDyMXGH1qQK3hVqshFolLN0S)
to have alphanumeric prefixes ([a-zA-Z0-9_]+).

This allows us to tell a generated password value
with a colon from an tagged binary.

If a value of, say, default_pass or ssl_options.password
cannot be parsed as a tagged value, it will be
parsed as a regular binary, because rabbit.schema
specifies multiple types as supported.

References #14233.
2025-08-11 13:25:36 -04:00
Michael Klishin 2024a4bc77
Merge pull request #14348 from udeeksha30-netizen/local_random_exchange
Add config option for enabling local_random_exchange
2025-08-11 13:23:56 -04:00
udeeksha30-netizen 781c14035e Addressed requested changes 2025-08-11 09:51:20 -07:00
udeeksha30-netizen 2afbc5eeb6 Add config option for enabling local_random_exchange 2025-08-11 07:47:08 -07:00
Deeksha 8a323b1888 Add config option for enabling local_random_exchange 2025-08-11 07:41:09 -07:00
dependabot[bot] 8f0ecb9059
[skip ci] Bump the dev-deps group across 4 directories with 1 update
Bumps the dev-deps group with 1 update in the /deps/rabbit/test/amqp_jms_SUITE_data directory: [org.assertj:assertj-core](https://github.com/assertj/assertj).
Bumps the dev-deps group with 1 update in the /deps/rabbitmq_mqtt/test/java_SUITE_data directory: [org.assertj:assertj-core](https://github.com/assertj/assertj).
Bumps the dev-deps group with 1 update in the /deps/rabbitmq_stream/test/rabbit_stream_SUITE_data directory: [org.assertj:assertj-core](https://github.com/assertj/assertj).
Bumps the dev-deps group with 1 update in the /deps/rabbitmq_stream_management/test/http_SUITE_data directory: [org.assertj:assertj-core](https://github.com/assertj/assertj).


Updates `org.assertj:assertj-core` from 3.27.3 to 3.27.4
- [Release notes](https://github.com/assertj/assertj/releases)
- [Commits](https://github.com/assertj/assertj/compare/assertj-build-3.27.3...assertj-build-3.27.4)

Updates `org.assertj:assertj-core` from 3.27.3 to 3.27.4
- [Release notes](https://github.com/assertj/assertj/releases)
- [Commits](https://github.com/assertj/assertj/compare/assertj-build-3.27.3...assertj-build-3.27.4)

Updates `org.assertj:assertj-core` from 3.27.3 to 3.27.4
- [Release notes](https://github.com/assertj/assertj/releases)
- [Commits](https://github.com/assertj/assertj/compare/assertj-build-3.27.3...assertj-build-3.27.4)

Updates `org.assertj:assertj-core` from 3.27.3 to 3.27.4
- [Release notes](https://github.com/assertj/assertj/releases)
- [Commits](https://github.com/assertj/assertj/compare/assertj-build-3.27.3...assertj-build-3.27.4)

---
updated-dependencies:
- dependency-name: org.assertj:assertj-core
  dependency-version: 3.27.4
  dependency-type: direct:development
  update-type: version-update:semver-patch
  dependency-group: dev-deps
- dependency-name: org.assertj:assertj-core
  dependency-version: 3.27.4
  dependency-type: direct:development
  update-type: version-update:semver-patch
  dependency-group: dev-deps
- dependency-name: org.assertj:assertj-core
  dependency-version: 3.27.4
  dependency-type: direct:development
  update-type: version-update:semver-patch
  dependency-group: dev-deps
- dependency-name: org.assertj:assertj-core
  dependency-version: 3.27.4
  dependency-type: direct:development
  update-type: version-update:semver-patch
  dependency-group: dev-deps
...

Signed-off-by: dependabot[bot] <support@github.com>
2025-08-09 18:28:24 +00:00
Deeksha febcdbb1b8 Add config option for enabling local_random_exchange 2025-08-08 10:33:11 -07:00
David Ansari edfd8ffede Assert confirm when responder publishes to reply queue 2025-08-08 16:43:09 +02:00
Jean-Sébastien Pédron eb8f631e22
proxy_protocol_SUITE: Wait for connection close
[Why]
`gen_tcp:close/1` simply closes the connection and doesn't wait for the
broker to handle it. This sometimes causes the next test to fail
because, in addition to that test's new connection, there is still the
previous one's process still around waiting for the broker to notice the
close.

[How]
We now wait for the connection to be closed at the end of a test case,
and wait for the connection list to have a single element when we want
to query the connnection name.
2025-08-08 10:12:58 +02:00
Jean-Sébastien Pédron 0a643ef339
feature_flags_v2_SUITE: Catch and log return value of peer:stop/1
[Why]
It failed at least once in CI. It should help us understand what went
on.
2025-08-08 10:12:58 +02:00
Jean-Sébastien Pédron bd1978ce9c
amqp_client_SUITE: Load test module on broker before using one of its anonymous functions
[Why]
Before this change, when the `idle_time_out_on_server/1` test case was runned first in the
shuffled test group, the test module was not loaded on the remote broker.
When the anonymous function was passed to meck and was executed, we got
the following crash on the broker:

    crasher:
      initial call: rabbit_heartbeat:'-heartbeater/2-fun-0-'/0
      pid: <0.704.0>
      registered_name: []
      exception error: {undef,
                           [{#Fun<amqp_client_SUITE.14.116163631>,
                             [#Port<0.45>,[recv_oct]],
                             []},
                            {rabbit_heartbeat,get_sock_stats,3,
                                [{file,"rabbit_heartbeat.erl"},{line,175}]},
                            {rabbit_heartbeat,heartbeater,3,
                                [{file,"rabbit_heartbeat.erl"},{line,155}]},
                            {proc_lib,init_p,3,
                                [{file,"proc_lib.erl"},{line,317}]},
                            {rabbit_net,getstat,[#Port<0.45>,[recv_oct]],[]}]}

This led to a failure of the test case later, when it waited for a
message from the connecrtion.

We do the same in two other test cases where this is likely to happen
too.

[How]
Loading the module first fixes the problem.
2025-08-08 10:12:57 +02:00
Jean-Sébastien Pédron 56b59c3d3e
amqp_client_SUITE: Trim "list_connections" output in one more place
[Why]
The reason is the same as for commit
ffaf919846. It should have been part of it
in fact, so an oversight from my end.
2025-08-08 10:12:57 +02:00
Jean-Sébastien Pédron 19ed2493a4
amqp_jms_SUITE: Increase time trap
[Why]
Maven took ages to fetch dependencies at least once in CI. The testsuite
failed because it reached the time trap limit.

[How]
Increase it from 2 to 5 minutes.
2025-08-08 10:12:57 +02:00
Jean-Sébastien Pédron ef9f59c58e
amqp_filter_sql_SUITE: Expect to wait for credits
[Why]
In CI, we observed failures where the sender runs out of credits and
don't expect that.

[How]
The `amqp_utils:send_messages/3` function already takes care of that.
Move this logic to a `send_message/2` function and use it in
`send_messages/3` and prevriously direct uses of
`amqp10_client:send_msg/2`.
2025-08-08 10:12:56 +02:00
Jean-Sébastien Pédron ed1cdb5987
per_user_connection_tracking_SUITE: Wait for the expected list of connections
[Why]
In CI, we sometimes observe two tracked connections in the return value.
I don't know yet what they are. Could it be a client that reopened its
crashed connection and because stats are updated asynchronously, we get
two tracked connections for a short period of time?
2025-08-08 10:12:56 +02:00
Jean-Sébastien Pédron 53d0b14726
per_user_connection_channel_tracking_SUITE: Wait for the expected list of connections
[Why]
In CI, we sometimes observe two tracked connections in the return value.
I don't know yet what they are. Could it be a client that reopened its
crashed connection and because stats are updated asynchronously, we get
two tracked connections for a short period of time?
2025-08-08 10:12:56 +02:00
Jean-Sébastien Pédron fd4c365889
rabbit_fifo_dlx_integration_SUITE: Increase a timeout in `delivery_limit/1`
[Why]
It looks to be too short in CI, causing failures from time to time.
2025-08-08 10:12:56 +02:00
David Ansari 04815c5979 Test setting Direct Reply-To queue in CC header 2025-08-08 09:49:50 +02:00
David Ansari 1906650de0 Increase test coverage for Direct Reply-to
Add more tests for the Direct Reply-to feature in AMQP 0.9.1.

This will help the future Direct Reply-To refactoring making sure the
existing behaviour won't break.
2025-08-07 17:39:25 +02:00
Michael Klishin 4bdec425c3
Merge pull request #14304 from rabbitmq/md/exchange-limit
Add a configurable limit for number of exchanges
2025-08-06 21:26:34 -04:00
Michael Klishin 5ddf7954eb
Introduce a few new rabbit_plugins and rabbit_nodes functions
Sometimes a plugin needs to list online peers
that are running, reachable, not under maintenance
and have a specific plugin enabled.

This commit introduces a few helper functions
to make such cluster member queries trivial.
2025-08-01 14:28:59 -04:00
Michael Davis d4e06ad8e3
Add a config option to limit the number of exchanges 2025-07-30 13:46:58 -04:00
Jean-Sébastien Pédron 0fb74baaa2
rabbit_stream_queue_SUITE: Wait for replicas in `shrink_coordinator_cluster/1`
[Why]
In CI, we sometimes get a failure when we try to forget node 3. The
CLI doesn't report the nature of the error unfortunately.

I suppose it's related to the fact that node 3 is stopped and forgotten
before all three replicas were ready when the stream queue was declared.
This is just a guess though and have no proof that it is the actual
error.

[How]
We wait for the replicas after declaring the stream queue.
2025-07-30 15:04:49 +02:00
Jean-Sébastien Pédron a44d541e5f
metrics_SUITE: Wait for ETS table to be up-to-date
... in several test cases.

[Why]
In CI or any slow and/or busy environment, it may take time for the ETS
tables to ge updated.
2025-07-30 15:04:49 +02:00
Jean-Sébastien Pédron 83b8a6ba38
amqp_client_SUITE: Ignore meck return value in `idle_time_out_on_server/1`
[Why]
Sometimes it returns `false` in CI. `meck:validate/1` can return false
in the module throws an exception. So perhaps a timing issue in CI where
the runner is usually slower than our working computers?
2025-07-30 15:04:48 +02:00
Jean-Sébastien Pédron ffaf919846
amqp_client_SUITE: Trim "list_connections" output before parsing it
[Why]
Sometimes, at least in CI, it looks like the output of the CLI is
prepended with a newline, sometimes not. This breaks the check of that
output.

[How]
We just trim the output before parsing it. The parsing already takes
care of trimming internal whitespaces.
2025-07-30 15:04:48 +02:00
Jean-Sébastien Pédron 6111c277b6
per_node_limit_SUITE: Wait for the channel count to be up-to-date
[Why]
In the `node_channel_limit` testcase, we open several channels and
verify the count of opened channels in all places but one: after the
first connection failure, when we try to open 3 channels.

Opening 3 channels in a row might not be tracked in time to reject the
third channel because the counter is updated asynchronously.

[How]
We simply wait for the counter to reach 5 before opening the third
channel.

We change all checks to use `?awaitMatch/3` in the process to be more
robust with timing issues.
2025-07-30 15:04:48 +02:00
Michal Kuratczyk 37b7a2a567
backing_queue_SUITE: Increase the restart time boundary
[Why]
ehie flaked today since the restart took 309ms, thus above
the allowed 100ms (outside of CI, it takes single-digit ms)

[How]
Increase the allowed time but also significantly increase next_seq_id.
This test exists because in the past we had an O(n) algorithm in CQ
recovery, leading to a slow recovery of even empty queues, if they had
a very large next_seq_id. Now that this operation is O(1), a much larger
next_seq_id shouldn't affect the time it takes to run
this test, while accidentally re-introducing an O(n) algorithm should
fail this test consistently.
2025-07-30 15:04:48 +02:00
Jean-Sébastien Pédron 22c09595d5
queue_type_SUITE: Be explicit about connection open+close
[Why]
The tests relied on `rabbit_ct_client_helpers` connection and channel
manager which doesn't seem to be robust. It causes more harm than helps
so far.

Hopefully, this will fix some test flakes in CI.
2025-07-30 15:04:47 +02:00
Jean-Sébastien Pédron f61374360a
per_user_connection_channel_limit_SUITE: Fix test flake in `single_node_list_in_user`
[Why]
This was the only place where a condition was checked once after a
connection close, instead of waiting for it to become true.

This caused some transient failures in CI when the connection tracking
took a bit of time to update and the check was performed before that.
2025-07-30 15:04:47 +02:00
Jean-Sébastien Pédron ab766981ac
cluster_minority_SUITE: Ensure cluster can be changed before partition
... in `remove_node_when_seed_node_is_leader/1` and
`remove_node_when_seed_node_is_follower/1`.

[Why]
The check was performed after the partition so far. It was incorrect
because if a cluster change was not permitted at the time of the
partition, it would not be afterwards. Thus there was a race condition
here.

[How]
Now, the check is performed before the partition.

Thanks to this new approach, we are sure of the state of node A and
don't need the cass block near the end of the test cases.

This should fix some test flakes we see locally and in CI.
2025-07-30 15:04:47 +02:00
Jean-Sébastien Pédron 1582ae6cee
quorum_queue_SUITE: Use less messages in `force_checkpoint_on_queue`
[Why]
The default checkpoint interval is 16384. Therefore with 20,000
messages published by the testcase, there is a chance a checkpoint is
created. This would hit an assertion in the testcase which expects no
checkpoints before it forces the creation of one. We see this happening
in CI. Not locally because the testcase runs fast enough.

[How]
The testcase now sends 10,000 messages. This is still a lot of messages
while staying under the default checkpoint interval.
2025-07-30 15:04:47 +02:00
Jean-Sébastien Pédron f973932a2d
quorum_queue_SUITE: Use Khepri fence before checking number of replicas
[Why]
When `wait_for_messages_ready/3` returns, we are sure that the replicas
are in the expected state. However, the `#amqqueue{}` record is updated
in Khepri, we don't know when all Khepri store members will be
up-to-date.

It can happen that `Server0` is not up-to-date when we query that record
to get the list of replicass, leading to a test failure.

[How]
First, the check is moved to its own function is `queue_utils`.

Then, if Khepri is being used, we use a Khepri fence to ensure previous
operations were applied on the given server. This way, we get a
consistent view of the `#amqqueue{}` record and thus the list of
replicas.
2025-07-30 15:04:47 +02:00
Jean-Sébastien Pédron bbcd04d931
feature_flags_SUITE: Fix style
[Why]
Several lines were crossing the 80-columns boundary, plus messages
without a capital first letter.
2025-07-30 15:04:46 +02:00
David Ansari 3543f2cffe Bump AMQP.Net Lite to v2.5.0 2025-07-29 08:38:43 +02:00