AMQP 1.0

hopf-amqp1 is an AMQP 1.0 async client (ISO/IEC 19464) targeting brokers with native AMQP 1.0 support (RabbitMQ 4's native AMQP 1.0 listener, ActiveMQ Artemis). Client-only: no broker in this crate. AMQP 1.0 shares only the four-byte AMQP magic with hopf-amqp's AMQP 0-9-1 (RabbitMQ classic protocol) — framing, the type system, and the connection/session/link model are unrelated.

Scope

AreaSupport
ProtocolAMQP 1.0 (ISO/IEC 19464) only — see AMQP 0-9-1 for the separate hopf-amqp crate
RoleClient only
AuthSASL PLAIN (when credentials are configured) or ANONYMOUS, auto-negotiated against what the peer advertises
Sessions / linksMultiple sessions per connection, multiple sender/receiver links per session
Flow controlSession-level incoming/outgoing window; per-link credit
Sendtransfer with header/properties/application-properties/data, auto-split across frames for messages larger than the negotiated max frame size
ReceiveStreamed to the application as transfer frames arrive, not buffered whole
Settlementaccept / reject / release / modify; outcome notifications for sent messages
TLSAMQPS via implicit TLS on dial

Architecture

Amqp1Client::connect
    → Runtime::connect(TcpConnectorConfig)
    → Amqp1ClientEndpoint (ProtocolHandler)
         protocol header → SASL mechanisms/init/outcome (if advertised)
         → AMQP protocol header (re-armed) → open/open
         → Amqp1ClientDriver::on_connection_open
         → begin_session / attach_sender / attach_receiver via Amqp1ClientControl
         ← transfer (streamed) → on_message_header/properties/application_properties/data
         ← disposition → on_delivery_outcome

Inbound is reactor-driven: socket readable → receive → Amqp1FrameParser → MessageParser for transfer payloads → driver callbacks. There is no application poll loop. The frame parser and message-section parser are both genuinely incremental push parsers — a large message body streams to the driver as bytes arrive rather than being buffered whole first.

SASL handshake

On connect, the client sends the AMQP protocol header for the SASL sub-protocol first. If the peer advertises PLAIN and credentials are configured, PLAIN is used; otherwise the client falls back to ANONYMOUS. After a successful sasl-outcome, the connection re-arms to expect the AMQP (non-SASL) protocol header, then proceeds with open. This re-arming happens correctly even when a peer pipelines the SASL outcome and the following AMQP header into the same TCP read — a real broker commonly does this, and the frame parser handles it within a single feed() call rather than needing a second read to notice the mode switch.

AMQP 1.0 layers sessions (RFC-1982 serial-numbered transfer windows over one connection) and links (named, unidirectional, credit-flow-controlled sender or receiver attachments within a session) on top of the connection — a structure AMQP 0-9-1 doesn't have. Amqp1ClientControl::begin_session opens a session on a channel; attach_sender/attach_receiver attach named links with a Source/Target address. A receiver must be given link credit (add_credit) before the peer will send it any deliveries.

Client

SPI mirrors the other Hopf async clients: Amqp1Client facade, Amqp1ClientHandlerFactory, flat Amqp1ClientDriver / Amqp1ClientControl.

Amqp1Client::new("127.0.0.1", 5672)
    .credentials("guest", "guest")
    .connect(&rt, Arc::new(Factory))?;

On on_connection_open, begin a session; on on_session_begin, attach a sender and/or receiver; on on_link_attached for a receiver, call add_credit before expecting deliveries; on on_credit for a sender, send is safe to call.

Messages

MessageHeader (durability, priority, TTL, …) and MessageProperties (content-type, message-id, correlation-id, …) are list-based sections; application-properties, delivery-annotations, and message-annotations are bare maps, encoded/decoded as such (not wrapped in a list — a spec-correctness detail this crate gets right). delivery-annotations, message-annotations, and footer sections are received as raw maps but not yet offered on the send side.

Examples

cargo test -p hopf-amqp1 --lib client::tests
cargo test -p hopf-amqp1 --features integration

No standalone cargo run example binary ships yet (unlike hopf-amqp's amqp-pub/amqp-consume) — see the client module docs for a full quick-start (connect, begin a session, attach a sender, send a message). The opt-in integration test targets a broker with native AMQP 1.0 support; defaults to 127.0.0.1:5672 / guest/guest (RabbitMQ 4 node addressing, /queues/<name>), overridable with HOPF_AMQP1_HOST, HOPF_AMQP1_PORT, HOPF_AMQP1_USER, HOPF_AMQP1_PASS, and HOPF_AMQP1_ADDRESS_STYLE=artemis for a plain queue-name address instead. HOPF_AMQP1_TLS_PORT / HOPF_AMQP1_TLS_CA configure the amqps (implicit TLS) test; it's skipped if no CA cert is found.

Limitations