Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

AMQP over WebSocket #13071

Open
wants to merge 2 commits into
base: main
Choose a base branch
from
Open

AMQP over WebSocket #13071

wants to merge 2 commits into from

Conversation

ansd
Copy link
Member

@ansd ansd commented Jan 15, 2025

Support AMQP 1.0 over WebSocket complying with https://docs.oasis-open.org/amqp-bindmap/amqp-wsb/v1.0/cs01/amqp-wsb-v1.0-cs01.html.

This PR contains two commits:

  1. Support AMQP over WebSocket in the Erlang client.
  2. The necessary changes outside of plugins rabbitmq_web_amqp and rabbitmq_web_amqp_examples.

@ansd ansd added this to the 4.1.0 milestone Jan 15, 2025
@mergify mergify bot added the make label Jan 15, 2025
@ansd ansd force-pushed the web-amqp-oss branch 2 times, most recently from 4ac4a64 to 1553522 Compare January 15, 2025 22:39
@ansd
Copy link
Member Author

ansd commented Jan 16, 2025

Adding a feature flag to main branch causes CI currently to fail.
#13082 provides a minimal reproducible example.

@ansd ansd marked this pull request as ready for review January 16, 2025 11:01
ansd added 2 commits January 16, 2025 16:31
 ## What?
Implement the AMQP over WebSocket Binding Committee Specification 01 in
the AMQP 1.0 Erlang client:
https://docs.oasis-open.org/amqp-bindmap/amqp-wsb/v1.0/cs01/amqp-wsb-v1.0-cs01.html

 ## Why?
1. This allows writing integration tests for the server implementation
   of AMQP over WebSocket.
2. Erlang and Elixir clients can use AMQP over WebSocket in environments
   where firewalls prohibit access to the AMQP port.

 ## How?
Use gun as WebSocket client.

The new module `amqp10_client_socket` handles socket operations (open, close, send) for:
* TCP sockets
* SSL sockets
* WebSockets

Prior to this commit, the amqp10_client_connection process closed only the
write end of the socket after it sent the AMQP close performative.
This commit removed premature socket closure because:
1. There is no equivalent feature provided in Gun since sending a
   WebSocket close frame causes Gun to cleanly close the connection for
   both writing and reading.
2. It's unnecessary and can result in unexpected and confusing behaviour on the server.
3. It's better practive to keep the TCP connection fully open until
   the AMQP closing handshake completes.
4. When amqp10_client_frame_reader terminates, it will cleanly close
   the socket for both writing and reading.
ansd added a commit that referenced this pull request Jan 22, 2025
 ## What?
This commit fixes #13040.

Prior to this commit, exchange federation crashed if the MQTT topic exchange
(`amq.topic` by default) got federated and MQTT 5.0 clients subscribed on the
downstream. That's because the federation plugin sends bindings from downstream
to upstream via AMQP 0.9.1. However, binding arguments containing Erlang record
`mqtt_subscription_opts` (henceforth binding args v1) cannot be encoded in AMQP 0.9.1.

 ## Why?
Federating the MQTT topic exchange could be useful for warm standby use cases.

 ## How?
This commit makes binding arguments a valid AMQP 0.9.1 table (henceforth
binding args v2).

Binding args v2 can only be used if all nodes support it. Hence binding
args v2 comes with feature flag `rabbitmq_4.1.0`. Note that the AMQP
over WebSocket
[PR](#13071) already
introduces this same feature flag. Although the feature flag subsystem
supports plugins to define their own feature flags, and the MQTT plugin
defined its own feature flags in the past, reusing feature flag
`rabbitmq_4.1.0` is simpler.

This commit also avoids database migrations for both Mnesia and Khepri
if feature flag `rabbitmq_4.1.0` gets enabled. Instead, it's simpler to
migrate binding args v1 to binding args v2 at MQTT connection establishment
time if the feature flag is enabled. (If the feature flag is disabled at
connection etablishment time, but gets enabled during the connection
lifetime, the connection keeps using bindings args v1.)

This commit adds two new suites:
1. `federation_SUITE` which tests that federating the MQTT topic
   exchange works, and
2. `feature_flag_SUITE` which tests the binding args migration from v1 to v2.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

Successfully merging this pull request may close these issues.

1 participant