2026.09.40 — 2026-09-24
Added
Let plugins tap, consume and send messages, and keep secrets (d2135c26)
Runtime plugins can now react to broker messages and store credentials without a client, thread or store of their own. Two beans are injected into every plugin, each bound to that plugin:
- PluginMessaging registers a tap (a bounded copy of what is routed to a queue, with existing consumers and producers untouched) or a consumer (the plugin accepts or rejects each message; anything but an accept is redelivered), and sends messages with a body, headers and properties. Deliveries go to the plugin's PluginMessageHandler bean on Studio's own threads. Studio installs and removes every broker object on every serving node, reclaims what a crash leaves behind, and removes a plugin's taps when it is disabled, uninstalled or purged.
- PluginSecrets stores named values encrypted with Studio's secret key, readable only by the plugin that stored them and deleted on purge. No interface returns a value; writes and deletes are audited by name.
Every registration and send acts for a user and needs that user's permissions on the cluster: message:read for a tap, message:read and queue:purge for a consumer, message:send to send. They are checked again on every pass (artemis-studio.plugins.messaging.reconcile-interval, 10s); a registration whose user loses one is suspended with the reason and resumes when it returns. Taps use capture's broker role, expiry and byte bound (artemis-studio.capture.*), and hold at most artemis-studio.plugins.messaging.tap-ring-size copies (10000).
Broker objects for taps are named artemis-studio.plugin.<instance>.*. That prefix is now reserved like capture's: the routing API refuses to create or delete a divert under it, and capture never covers it.
The plugin guide's new "Messages and secrets" section documents the API. The change is additive; the plugin contract version is unchanged. See ADR-0111.