# Architecture (/connectors/rabbitmq/concepts/architecture)



The KubeMQ **RabbitMQ (AMQP 0-9-1) connector** is an embedded, wire-protocol bridge inside
kubemq-server that speaks the RabbitMQ dialect on plain port **5672** and TLS/AMQPS port
**5671**. The connector is &#x2A;*opt-in (disabled by default)** — enable it with
`CONNECTORS_AMQP_ENABLE=true` (Docker) or `spec.amqp.enabled: true` (Kubernetes). Any
standard AMQP 0-9-1 client connects to it with **only a connection-string change** — no code
changes, no library swap, no KubeMQ SDK.

Unlike the AMQP 1.0 connector (which can touch all five KubeMQ patterns), the RabbitMQ
connector bridges the AMQP 0-9-1 wire protocol onto exactly one KubeMQ primitive: the
**Queue**. This single fact drives the entire mental model.

<Callout type="info">
  **Everything is a Queue.** Every AMQP queue maps to exactly one KubeMQ **Queue** channel
  named `amqp.{vhost}.{queue}`. Exchanges and bindings are **virtual** — connector-side
  routing metadata resolved at publish time, not data stores. AMQP only ever touches the
  KubeMQ Queue primitive; there is no exchange "storage."
</Callout>

## How AMQP 0-9-1 maps to KubeMQ [#how-amqp-0-9-1-maps-to-kubemq]

A publish always resolves to one or more KubeMQ Queue channels. The connector resolves the
exchange routing (default / direct / fanout / topic / headers) into a deduplicated set of
target queues **at publish time**, then writes the message to each queue's KubeMQ channel
`amqp.{vhost}.{queue}` through the message broker.

<Mermaid
  chart="`
graph TB
PUB[&#x22;basic.publish(exchange, routing-key)&#x22;]
EX{{&#x22;Exchange routing (virtual)<br/>default · direct · fanout · topic · headers&#x22;}}
SET[&#x22;Deduplicated set of target queues<br/>(per-queue authorization)&#x22;]
CH[&#x22;amqp.{vhost}.{queue} ×N&#x22;]
BROKER[&#x22;Message Broker&#x22;]

PUB --> EX
EX --> SET
SET --> CH
CH --> BROKER

class PUB client
class EX,SET connector
class CH,BROKER broker
`"
/>

*A publish resolves through virtual exchange routing into a deduplicated set of target queues; each maps to a KubeMQ Queue channel `amqp.{vhost}.{queue}` and is written through the message broker.*

The exchange types resolve as in RabbitMQ, but the result is always a set of KubeMQ Queue
channels:

| Exchange type      | Routing rule                                              |
| ------------------ | --------------------------------------------------------- |
| **default** (`""`) | The routing key **is** the queue name (implicit binding). |
| **direct**         | Exact routing-key match against the bindings.             |
| **fanout**         | All bound queues (routing key ignored).                   |
| **topic**          | Trie match (`*` = one word, `#` = zero-or-more words).    |
| **headers**        | `x-match` against the header bindings.                    |

Matched queues are **deduplicated** — a message matching multiple bindings to the same queue
is delivered exactly **once**. If the routed set is empty, the publish returns
`basic.return (312 NO_ROUTE)` when `mandatory=true`, otherwise it is silently dropped.

### Channel mapping [#channel-mapping]

The channel name is `amqp.{vhost}.{queue}`. AMQP vhost `/` maps to the configured
`DefaultVhost` segment (literal `"default"`):

| AMQP queue | Vhost         | KubeMQ channel        |
| ---------- | ------------- | --------------------- |
| `orders`   | `/` (default) | `amqp.default.orders` |
| `hello`    | `/`           | `amqp.default.hello`  |
| `jobs`     | `workers`     | `amqp.workers.jobs`   |

The full channel name (prefix + vhost + queue) is capped at 255 chars, and queue/vhost
names must not contain `;`, `:`, `*`, `>`, whitespace, or end with `.`. See
[Channel mapping](/connectors/rabbitmq/reference/channel-mapping) for the grammar and
the property/header mapping.

## The connector stack [#the-connector-stack]

The connector terminates the AMQP 0-9-1 wire protocol and translates it onto KubeMQ Queue
operations. A single `amqpmux` front door classifies each connection by its 8-byte AMQP
protocol header and dispatches AMQP 0-9-1 traffic to this engine (and AMQP 1.0 traffic to
the AMQP 1.0 engine), so the two dialects coexist on ports 5672/5671.

<Mermaid
  chart="`
graph TB
CLIENT[&#x22;AMQP 0-9-1 client<br/>amqp:// :5672 / amqps:// :5671&#x22;]
SASL[&#x22;SASL PLAIN handshake<br/>(password = KubeMQ JWT; user cosmetic)&#x22;]
ROUTE[&#x22;Exchange routing (virtual)<br/>resolved at publish time&#x22;]
AUTHZ[&#x22;Per-queue authorization<br/>(Write on publish)&#x22;]
SEND[&#x22;SendQueueMessage(s)Batch&#x22;]
CH[&#x22;KubeMQ Queue channel<br/>amqp.{vhost}.{queue}&#x22;]
BROKER[&#x22;Message Broker<br/>(durable store)&#x22;]

CLIENT --> SASL
SASL --> ROUTE
ROUTE --> AUTHZ
AUTHZ --> SEND
SEND --> CH
CH --> BROKER

class CLIENT client
class SASL,ROUTE,AUTHZ,SEND connector
class CH,BROKER broker
`"
/>

*The connector authenticates over SASL PLAIN, resolves virtual exchange routing, authorizes each target queue, and batch-writes to the KubeMQ Queue channel backed by the message broker's durable store.*

* **SASL PLAIN only.** On a secured broker the username is cosmetic and the password carries
  a KubeMQ JWT; identity is `claims.ClientID`. Because the JWT travels in the SASL PLAIN
  password in cleartext at the AMQP layer, production deployments must use the TLS listener
  (5671). See [Authentication](/connectors/rabbitmq/how-to/authentication).
* **Native RPC.** Request/reply uses RabbitMQ's `amq.rabbitmq.reply-to` (direct reply-to);
  there is **no gRPC responder** anywhere in the connector. See
  [RPC](/connectors/rabbitmq/how-to/rpc).

## Cross-protocol interop [#cross-protocol-interop]

Because every AMQP queue is a normal KubeMQ Queue channel, AMQP and gRPC/REST clients
interoperate on the same channel.

<Mermaid
  chart="`
graph LR
AMQP[&#x22;AMQP 0-9-1 client<br/>queue: orders&#x22;]
GRPCCLIENT[&#x22;gRPC / REST client<br/>channel: amqp.default.orders&#x22;]
BROKER[&#x22;Message Broker&#x22;]

AMQP -- &#x22;publish&#x22; --> BROKER
BROKER -- &#x22;consume&#x22; --> GRPCCLIENT
GRPCCLIENT -- &#x22;produce&#x22; --> BROKER
BROKER -- &#x22;consume&#x22; --> AMQP

class AMQP,GRPCCLIENT client
class BROKER broker
`"
/>

*The same KubeMQ Queue channel backs both sides, so an AMQP 0-9-1 client and a gRPC/REST client interoperate transparently.*

Header and metadata translation differs by direction:

| Direction            | What the consumer sees                                                                                                                                                           |
| -------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| **AMQP → AMQP**      | Routing context is native: a delivery shows `exchange`, `routing-key`, and the original AMQP headers.                                                                            |
| **AMQP → gRPC/REST** | AMQP headers are wrapped as `Metadata = {"amqp_headers":{...}}` (always set, even when empty). E.g. header `trace=abc-123` → `{"amqp_headers":{"trace":"abc-123"}}`.             |
| **gRPC/REST → AMQP** | Native (non-enveloped) gRPC metadata surfaces as the AMQP header `x-kubemq-metadata`. E.g. gRPC `metadata="native-metadata"` → AMQP header `x-kubemq-metadata: native-metadata`. |

The `{"amqp_headers":{...}}` envelope is an **interop concern**, not a default-path surprise:
a pure AMQP→AMQP round-trip surfaces headers natively. See
[Channel mapping](/connectors/rabbitmq/reference/channel-mapping) for the full
property/header ⇄ Tag/Metadata table.

## Related [#related]

<Cards>
  <Card title="Channel mapping" href="/connectors/rabbitmq/reference/channel-mapping" description="The amqp.{vhost}.{queue} grammar, name constraints, and the property/header mapping." />

  <Card title="Exchanges and routing" href="/connectors/rabbitmq/concepts/exchanges-and-routing" description="How default, direct, fanout, topic, and headers exchanges resolve to queues at publish time." />

  <Card title="Work queues" href="/connectors/rabbitmq/how-to/work-queues" description="Competing consumers and fair dispatch over a single KubeMQ Queue channel." />

  <Card title="RPC" href="/connectors/rabbitmq/how-to/rpc" description="Request/reply over the native amq.rabbitmq.reply-to direct reply-to mechanism." />
</Cards>
