activemq://¶
Producer + consumer for ActiveMQ brokers (both ActiveMQ Classic
5.x and ActiveMQ Artemis 2.x), speaking STOMP 1.2 via
github.com/go-stomp/stomp/v3.
activemq:// is a thin alias on top of stomp://
— same wire protocol, same URI param surface, same defaults. The two
schemes share every line of code; pick activemq:// when you want
ActiveMQ targets to be explicit in your YAML.
Note on protocol choice. Helix speaks STOMP 1.2 rather than OpenWire (ActiveMQ Classic's native binary protocol) — Go has no first-class OpenWire client, and modern ActiveMQ Artemis ships with OpenWire disabled by default. For AMQP 1.0 use
amqp://.
URI shape¶
The destination is sent verbatim as the STOMP destination header.
Common conventions:
| Style | Example | What it means |
|---|---|---|
| JMS queue path | activemq:///queue/orders |
Point-to-point queue. |
| JMS topic path | activemq:///topic/events |
Pub/sub topic. |
| Bare name | activemq://orders.in |
Broker maps to its default destination type (queue on ActiveMQ Classic). |
Specify the broker URL via the brokerURL= query param (the
authority before the ? is part of the destination path, NOT the
broker host):
Body shape¶
Request (producer):
| Body type | Wire shape |
|---|---|
[]byte |
STOMP BytesMessage (content-type from headers, or auto-set if not present). |
string |
STOMP TextMessage. |
io.Reader |
Drained, then sent as BytesMessage. |
Response (consumer — each inbound STOMP MESSAGE becomes one exchange):
| Body | When |
|---|---|
[]byte |
Always — the STOMP body. |
| Headers | STOMP headers pass through subject to headerIncludePattern / headerExcludePattern. Reserved: destination, message-id, subscription, reply-to, content-length, content-type. |
Operations¶
Producer-only — the wire is one-shot SEND per exchange. Consumer is a long-lived STOMP SUBSCRIBE that emits one Helix exchange per received MESSAGE.
| Pattern | URI | Body in | Body out |
|---|---|---|---|
| Fire-and-forget send (default) | to: activemq:///queue/orders |
bytes/string | unchanged |
| Request/reply (InOut) | to: activemq:///queue/rpc?replyTo=/temp-queue/reply + InOut exchange |
bytes/string | reply body |
| Subscribe | trigger: { uri: activemq:///queue/orders } |
n/a | bytes |
| Durable subscribe | trigger: { uri: activemq:///topic/events?durable=true&subscriptionName=worker1&clientId=helix-1 } |
n/a | bytes |
Headers¶
Inputs (producer SEND headers):
| Header | Effect |
|---|---|
Standard exchange content-type |
Sent verbatim as STOMP content-type. |
correlation-id |
Sent verbatim. Used by InOut to match the reply. |
reply-to |
Overrides the URI replyTo= value for this message. |
priority |
Overrides URI priority= for this message. |
expires |
Overrides URI timeToLive= for this message (epoch-ms). |
| Custom keys | Pass-through subject to the include/exclude regex pair. |
Outputs (consumer MESSAGE → exchange headers):
Reserved STOMP frame headers (destination, message-id,
subscription, reply-to, content-length, content-type) always
pass through. User headers follow headerIncludePattern /
headerExcludePattern.
Parameters¶
Full URI-param surface is documented under
stomp:// — activemq:// accepts the
identical set. Quick reference:
| Group | Keys |
|---|---|
| Connection | brokerURL, brokerHost, brokerPort, host, login, passcode, version, clientId, heartBeat, connectTimeout, readTimeout, writeTimeout, maxReconnectAttempts, recoveryInterval, testConnectionOnStartup |
| TLS | tlsCAFile, tlsCertFile, tlsKeyFile, tlsInsecureSkipVerify, tlsMinVersion, tlsMaxVersion, tlsCipherSuites |
| Common | replyTo, disableReplyTo, requestTimeout, receiveTimeout |
| Consumer | ack, concurrentConsumers, selector, durable, subscriptionName, prefetch |
| Producer | persistent, priority, timeToLive, allowNullBody, useMessageIDAsCorrelationID |
| Headers | header.<NAME>, headerIncludePattern, headerExcludePattern |
Examples¶
Producer — fan a Kafka topic into an ActiveMQ queue¶
workflows:
- id: kafka-to-activemq
trigger:
uri: kafka://orders.kafka?bootstrapServers=kafka:9092&groupId=mq-fanout
steps:
- target: "activemq:///queue/orders?brokerURL=tcp://mq:61613&persistent=true&priority=4"
Body is the Kafka value; STOMP persistent flag makes the broker
journal the message before ack-ing the SEND.
Consumer — durable topic subscriber¶
workflows:
- id: events-listener
trigger:
uri: activemq:///topic/events
params:
brokerURL: "tcp://mq:61613"
clientId: "helix-events"
durable: "true"
subscriptionName: "events-helix-1"
ack: "client"
prefetch: "100"
steps:
- target: "log://event"
durable=true + subscriptionName= + clientId= together create a
named durable subscription that survives broker restarts. ack=client
means Helix sends an ACK frame only after the route returns
successfully — failures cause redelivery.
Request / reply over a temporary queue¶
workflows:
- id: rpc-caller
trigger:
uri: http-server://0.0.0.0:8080/quote
steps:
# InOut over activemq:// — Helix opens a temp reply queue, sends,
# blocks for the matching correlation-id, returns the reply body.
- target: "activemq:///queue/quote.req?brokerURL=tcp://mq:61613&replyTo=/temp-queue/quote.reply&requestTimeout=10s"
Selector — broker-side filter¶
The selector URI param maps directly to STOMP's selector
SUBSCRIBE header. JMS selector syntax — broker-dependent feature
support (Artemis: full SQL92 subset; ActiveMQ Classic: simpler).
Failure modes¶
| Error | Cause | Fix |
|---|---|---|
activemq testConnectionOnStartup: … |
testConnectionOnStartup=true and broker rejected the CONNECT (bad auth, wrong port, TLS handshake fail). |
Check brokerURL, login, passcode, TLS params. |
dial tcp …: connection refused |
Broker not running, wrong port, firewall. | Default STOMP port is 61613 (61612 for ssl://). |
CONNECT: invalid credentials |
login/passcode wrong. | Verify broker user. |
SUBSCRIBE: unknown destination (Artemis) |
Auto-create disabled and the address doesn't exist. | Pre-create on the broker, or enable auto-create in broker.xml. |
| Producer hangs at SEND | Broker is back-pressured (queue full) and Helix has persistent=true. |
Raise broker quotas, lower message rate, or use persistent=false for non-critical data. |
durable=true requires subscriptionName |
Validation. | Set both subscriptionName= and clientId=. |
When to pick activemq:// vs stomp:// vs amqp://¶
| Use | Component |
|---|---|
| Broker is ActiveMQ (Classic or Artemis), and you want this to be explicit in YAML | activemq:// |
| Broker is RabbitMQ-with-STOMP-plugin or HornetQ, and you want broker-agnostic config | stomp:// |
| Broker is Artemis (or any AMQP 1.0 broker) and you want better message tracing / interop | amqp:// |
| Broker is RabbitMQ-with-AMQP-0-9-1 (the default RabbitMQ protocol) | rabbitmq:// |
See also¶
docs/reference/components/stomp.md— sibling broker-agnostic scheme.docs/reference/components/amqp.md— AMQP 1.0 (for Artemis users who want richer wire semantics).