Commit Graph

809 Commits

Author SHA1 Message Date
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
Michael Klishin c791e518e1
Tweak mergify.yml for 4.2.x 2025-09-02 03:48:15 -04:00
Michael Klishin 0bc0b6171e
mergify.yml: updates for the v4.2.x era 2025-09-01 12:18:49 -04:00
dependabot[bot] 275c62d46c
Bump google-github-actions/auth from 2.1.12 to 3.0.0
Bumps [google-github-actions/auth](https://github.com/google-github-actions/auth) from 2.1.12 to 3.0.0.
- [Release notes](https://github.com/google-github-actions/auth/releases)
- [Changelog](https://github.com/google-github-actions/auth/blob/main/CHANGELOG.md)
- [Commits](https://github.com/google-github-actions/auth/compare/v2.1.12...v3.0.0)

---
updated-dependencies:
- dependency-name: google-github-actions/auth
  dependency-version: 3.0.0
  dependency-type: direct:production
  update-type: version-update:semver-major
...

Signed-off-by: dependabot[bot] <support@github.com>
2025-08-29 18:03:26 +00:00
Aitor Perez 771874ca6c
Fix OCI trigger in PR
The output is of type bool, and the comparison was checking for string
'true'. In JS 'true' is not equal true (bool) 🤷
2025-08-28 11:03:17 +01:00
Michael Klishin 0c35f0fec3
Workflows: bump expected IBM MQ tag to 9.4.0.12 2025-08-12 20:31:14 -04:00
dependabot[bot] 8c53b69b1a
build(deps): bump actions/checkout from 4 to 5
Bumps [actions/checkout](https://github.com/actions/checkout) from 4 to 5.
- [Release notes](https://github.com/actions/checkout/releases)
- [Changelog](https://github.com/actions/checkout/blob/main/CHANGELOG.md)
- [Commits](https://github.com/actions/checkout/compare/v4...v5)

---
updated-dependencies:
- dependency-name: actions/checkout
  dependency-version: '5'
  dependency-type: direct:production
  update-type: version-update:semver-major
...

Signed-off-by: dependabot[bot] <support@github.com>
2025-08-12 23:05:28 +00:00
Jean-Sébastien Pédron 8d0f1001af
rabbitmq_cli: Create a symlink to test node's logs
[Why]
This doesn't replicate the common_test logs layout, but it will be good
enough to let our GitHub Actions workflow to upload the logs without
specific instructions in the workflow.
2025-08-08 10:12:56 +02:00
Marcial Rosales 8fb36030a5 Add spring authorization server for testing purposes
with Selenium. And ci job to build the docker image
2025-08-06 10:33:49 +02:00
Michael Klishin 018c4b189b
Closes #14327 2025-08-04 11:15:18 -04:00
dependabot[bot] eb6eb953d4
Bump google-github-actions/auth from 2.1.11 to 2.1.12
Bumps [google-github-actions/auth](https://github.com/google-github-actions/auth) from 2.1.11 to 2.1.12.
- [Release notes](https://github.com/google-github-actions/auth/releases)
- [Changelog](https://github.com/google-github-actions/auth/blob/main/CHANGELOG.md)
- [Commits](https://github.com/google-github-actions/auth/compare/v2.1.11...v2.1.12)

---
updated-dependencies:
- dependency-name: google-github-actions/auth
  dependency-version: 2.1.12
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
2025-08-01 18:04:45 +00:00
dependabot[bot] 95746940fb
Bump google-github-actions/auth from 2.1.10 to 2.1.11
Bumps [google-github-actions/auth](https://github.com/google-github-actions/auth) from 2.1.10 to 2.1.11.
- [Release notes](https://github.com/google-github-actions/auth/releases)
- [Changelog](https://github.com/google-github-actions/auth/blob/main/CHANGELOG.md)
- [Commits](https://github.com/google-github-actions/auth/compare/v2.1.10...v2.1.11)

---
updated-dependencies:
- dependency-name: google-github-actions/auth
  dependency-version: 2.1.11
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
2025-07-21 20:11:29 +00:00
Michal Kuratczyk 6acc2b15ea
[skip ci] update version in discussion templates 2025-07-10 11:52:29 +02:00
Michal Kuratczyk cedace734b
[skip ci] add previous_version input to test-make-tests
Trigger a 4.2.x alpha release build / trigger_alpha_build (push) Has been cancelled Details
2025-07-09 11:57:08 +02:00
Michal Kuratczyk 6e4058c3ba
[skip ci] Add input to 3.13 mixed version test request
Trigger a 4.2.x alpha release build / trigger_alpha_build (push) Waiting to run Details
Test (make) / Build and Xref (1.18, 26) (push) Has been cancelled Details
Test (make) / Build and Xref (1.18, 27) (push) Has been cancelled Details
Test (make) / Build and Xref (1.18, 28) (push) Has been cancelled Details
Test (make) / Test (1.18, 28, khepri) (push) Has been cancelled Details
Test (make) / Test (1.18, 28, mnesia) (push) Has been cancelled Details
Test (make) / Test mixed clusters (1.18, 28, khepri) (push) Has been cancelled Details
Test (make) / Test mixed clusters (1.18, 28, mnesia) (push) Has been cancelled Details
Test (make) / Type check (1.18, 28) (push) Has been cancelled Details
2025-07-09 11:46:13 +02:00
Michal Kuratczyk d0dad7375a
Run mixed-version tests with 3.13 weekly 2025-07-08 10:52:24 +02:00
Michal Kuratczyk d2111d35db
Add previous_version input for mixed-version tests 2025-07-08 10:52:24 +02:00
Michal Kuratczyk 3033154717
Cache ActiveMQ to reduce downloads/flakes 2025-06-27 15:05:16 +02:00
Michal Kuratczyk f0705acd19
Disable dialyzer for some modules
Elixir 1.18 comes with a JSON package which leads to errors like this:

```
Duplicate modules: [["/home/runner/work/_temp/.setup-beam/elixir/bin/../lib/elixir/ebin/Elixir.JSON.Encoder.Float.beam",
                     "/home/runner/work/rabbitmq-server/rabbitmq-server/deps/json/ebin/Elixir.JSON.Encoder.Float.beam"],
```
2025-06-27 12:42:57 +02:00
Michal Kuratczyk 57b1ec13fd
Use OTP28/Elixir 1.18 in the pipelines 2025-06-27 09:49:35 +02:00
Michal Kuratczyk 2b83238e72
[skip ci] Add 4.1.1 to discussion template 2025-06-16 09:14:08 +02:00
Aitor Perez 5a83ec98b1
ci: nightly OCI project version without leading 'v'
The leading `v` in the PROJECT_VERSION is breaking some tests, that
expect to parse the version returned by the broker, without a leading
`v`.
2025-06-12 10:36:27 +01:00
Aitor Perez d304d98ac1
ci: build nightly with `{{branch_name}}-{{otp_version}}` tag 2025-06-11 10:08:22 +01:00
David Ansari eccf9fee1e Run Quorum Queue property test on different OTP versions
Trigger a 4.2.x alpha release build / trigger_alpha_build (push) Has been cancelled Details
Test (make) / Build and Xref (1.17, 26) (push) Has been cancelled Details
Test (make) / Build and Xref (1.17, 27) (push) Has been cancelled Details
Test (make) / Test (1.17, 27, khepri) (push) Has been cancelled Details
Test (make) / Test (1.17, 27, mnesia) (push) Has been cancelled Details
Test (make) / Test mixed clusters (1.17, 27, khepri) (push) Has been cancelled Details
Test (make) / Test mixed clusters (1.17, 27, mnesia) (push) Has been cancelled Details
Test (make) / Type check (1.17, 27) (push) Has been cancelled Details
## What?

PR #13971 added a property test that applies the same quorum queue Raft
command on different quorum queue members on different Erlang nodes
ensuring that the state machine ends up in exaclty the same state.
The different Erlang nodes run the **same** Erlang/OTP version however.

This commit adds another property test where the different Erlang nodes
run **different** Erlang/OTP versions.

 ## Why?

This test allows spotting any non-determinism that could occur when
running quorum queue members in a mixed version cluster, where mixed
version means in our context different Erlang/OTP versions.

 ## How?

CI runs currently tests with Erlang 27.

This commit starts an Erlang 26 node in docker, specifically for the
`rabbit_fifo_prop_SUITE`.

Test case `two_nodes_different_otp_version` running Erlang 27 then transfers
a few Erlang modules (e.g. module `rabbit_fifo`) to the Erlang 26 node.
The test case then runs the Ra commands on its own node in Erlang 27 and
on the Erlang 26 node in Docker.

By default, this test case is skipped locally.
However, to run this test case locally, simply start an Erlang node as
follows:
```
erl -sname rabbit_fifo_prop@localhost
```
2025-06-06 17:08:28 +02:00
Aitor Perez 4f35561ed6
ci: build nightly OCI image
It's a middle ground between building on every commit, and not building
at all. We currently have a workflow to build the OCI on every PR.
However, building on every PR does not cover some use cases. For
example, providing an image to a user to preview some changes coming in
the next minor or patch. Another use case: compare main with a PR in
Kubernetes.

It's better to have a separate workflow, even at the expense of
duplication, because the "on schedule" trigger only runs on the default
branch of the repository. This "limitation" makes it complicated to
extend the current "build OCI on PRs" to also build nightly for main and
release branches.
2025-06-04 17:03:25 +01:00
Aitor Perez 40fcc1cdf3
ci: fix indentation in selenium workflow
From #14014, we learned that the indentation was causing workflows to
not trigger. However, this did not seem to affect when the workflow file
itself was changed. In any case, YAML is sensible to indentation,
therefore this change is 'correct'. Removing single quotes from paths
with '*' at the end, because it is not required according to YAML and
GitHub documentation.

The path triggers now match the Selenium workflow that runs on commits
to main and release branches.
2025-06-03 11:03:46 +01:00
Marcial Rosales efcbde4f34 Add missing id tag 2025-05-29 09:27:26 +02:00
Marcial Rosales 94cba43e75 Relocate temp folder from /tmp to /var 2025-05-28 13:01:46 +02:00
Diana Parra Corbacho 1616b7f295 Update Github workflows with new federation plugins 2025-05-27 07:55:29 +02:00
Aitor Perez 4efb3df39e
CI: tweak OCI build triggers
Building on push to any branch is wasteful and unnecessary, because most
of built images are never used. The workflow dispatch trigger covers the
use case to build an image from the latest commit in a branch.

The use case to validate/QA a PR is now covered by on pull request
trigger. This trigger has a caveat: PRs from forks won't produce a
docker image.

Why?
Because PRs from forks do not inject rabbitmq-server secrets. This is a
security mechanism from GitHub, to protect repository secrets.

With this trigger is possible to QA/validate PRs from other Core team
members. Technically, anyone with 'write' access to our repo to push
branches.
2025-05-13 11:10:19 +01:00
dependabot[bot] 715823c5bb
Bump google-github-actions/auth from 2.1.9 to 2.1.10
Bumps [google-github-actions/auth](https://github.com/google-github-actions/auth) from 2.1.9 to 2.1.10.
- [Release notes](https://github.com/google-github-actions/auth/releases)
- [Changelog](https://github.com/google-github-actions/auth/blob/main/CHANGELOG.md)
- [Commits](https://github.com/google-github-actions/auth/compare/v2.1.9...v2.1.10)

---
updated-dependencies:
- dependency-name: google-github-actions/auth
  dependency-version: 2.1.10
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
2025-04-25 18:39:38 +00:00
dependabot[bot] 0ea1b4b5e6
Bump google-github-actions/auth from 2.1.8 to 2.1.9
Bumps [google-github-actions/auth](https://github.com/google-github-actions/auth) from 2.1.8 to 2.1.9.
- [Release notes](https://github.com/google-github-actions/auth/releases)
- [Changelog](https://github.com/google-github-actions/auth/blob/main/CHANGELOG.md)
- [Commits](https://github.com/google-github-actions/auth/compare/v2.1.8...v2.1.9)

---
updated-dependencies:
- dependency-name: google-github-actions/auth
  dependency-version: 2.1.9
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
2025-04-24 18:59:17 +00:00
Jean-Sébastien Pédron ac90d13af6
GitHub Actions: Use RabbitMQ 4.0.9 for mixed-version testing
[Why]
We used a 4.0.x snapshot so far because we needed RabbitMQ 4.0.x to use
khepri_mnesia_migration 0.7.2.

RabbitMQ 4.0.9 was released with this update of khepri_mnesia_migration,
thus we don't need the snapshot anymore.
2025-04-23 10:45:50 +02:00
Michael Klishin d265fdd889
Drop the 4.0.x alphas workflow
Now that 4.1.0 is out, 4.0.x binary releases will
no longer be available publicly.

(cherry picked from commit cf98ba5a8c)

Conflicts:
	.github/workflows/release-4.0.x-alphas.yaml
(cherry picked from commit 4dc2395d63)
2025-04-19 14:25:41 -04:00
Michal Kuratczyk e90b47f7e1
[skip ci] Add new versions to GH Discussion template 2025-04-16 14:15:32 +02:00
Michael Klishin 95332ddad1
Use a functional token for rabbitmq/server-packages event dispatch 2025-04-15 01:00:20 -04:00
Jean-Sébastien Pédron 2754fb7d05
GitHub Actions: Use a 4.0.x snapshot for mixed-version testing
This is to make sure the old node uses the latest
khepri_mnesia_migration patch release.
2025-04-08 18:47:27 +02:00
Aitor Pérez Cedres 24a0f29ae1
Merge pull request #13534 from rabbitmq/ci/refine-oci-triggers
Refine CI triggers for building OCI
2025-03-17 13:29:33 +00:00
Aitor Perez 3596ee9533
CI: use OTP 27 for tests
Erlang 27 is fully supported in main and v4.1.x. Support for Erlang 26
in v4.1 remains. It's better to "drop" erlang 26 from CI because, at the
moment, our PRs and commits to main trigger about 270 jobs. If we just
add '27' to the matrix, we would spawn ~216 more jobs, totalling around
496 jobs per PR and commit to main. That's simply too much, because it's
reaching the usage limits of Github Actions [1], namely the 256 limit of
matrix jobs.

[1]
https://docs.github.com/en/actions/administering-github-actions/usage-limits-billing-and-administration#usage-limits
2025-03-17 11:23:21 +00:00
Aitor Perez 8fc3ce990a
Trigger OCI builds on changes to its Dockerfile 2025-03-17 10:53:09 +00:00
Aitor Perez ed033772cb
Trigger OCI builds only on code changes
Prior to this change, we built the OCI for almost any change. That
doesn't make sense. For example, when there were changes to CI, it
didn't make because RabbitMQ had not changed.

CI will now build dev OCI images when there are actual code changes, or
changes to rabbit dependencies.
2025-03-17 10:53:02 +00:00
Aitor Perez 07adc3e571
Remove Bazel files 2025-03-13 13:42:34 +00:00
Michael Klishin 36be7bbe0d
Alpha release workflows: produce 4.2.x releases off of main
and 4.1.x ones off of v4.1.x, which is getting closer
to the RC stage.
2025-03-13 00:55:07 -04:00
Aitor Pérez Cedres ad0c209478
Merge pull request #13425 from rabbitmq/fix-selenium-log-collection
Fix log collection in Selenium workflows
2025-03-12 10:00:19 +00:00
Jean-Sébastien Pédron 2c66191043
amqp_client_SUITE: Use a dedicated CI job for this testsuite
[Why]
This testsuite is very unstable and it is difficult to debug while it is
part of a `parallel-ct` group. It also forced us to re-run the entire
`parallel-ct` group just to retry that one testsuite.
2025-03-07 14:48:32 +01:00
Arnaud Cogoluègnes 852f8243a5
Add one Maven project to dependabot on 3.13 branch 2025-03-05 15:02:39 +01:00
dependabot[bot] 496a827a5d
Bump peter-evans/create-pull-request from 7.0.7 to 7.0.8
Bumps [peter-evans/create-pull-request](https://github.com/peter-evans/create-pull-request) from 7.0.7 to 7.0.8.
- [Release notes](https://github.com/peter-evans/create-pull-request/releases)
- [Commits](https://github.com/peter-evans/create-pull-request/compare/v7.0.7...v7.0.8)

---
updated-dependencies:
- dependency-name: peter-evans/create-pull-request
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
2025-03-04 18:54:07 +00:00
Michal Kuratczyk 10693d37f2
[skip ci] Add 4.0.6 an 4.0.7 to the discussion template 2025-02-28 13:25:02 +01:00
Aitor Perez d95fc550b6
Fix log collection in Selenium workflows
Prior to this commit, if a test failed, the script 'run-suites.sh' would
exit with non-zero status, stopping the exection of the job; therefore,
the steps to move the logs to the expected location won't be executed.
This commit separates the tests from the log preparation.
2025-02-25 17:23:21 +00:00
Aitor Perez 6c10cea3ad
CI: remove selenium summary jobs 2025-02-25 11:51:31 +00:00