pub trait SpoePlugin:
Debug
+ Send
+ Sync {
// Required methods
fn init(&mut self, context: &PluginContext) -> RResult<(), RBoxError>;
fn process(
&self,
message: &SpoeMessage,
) -> RResult<ProcessingResult, RBoxError>;
fn name<'_self>(&'_self self) -> RStr<'_self>;
fn version<'_self>(&'_self self) -> RStr<'_self>;
fn shutdown(&self);
// Provided methods
fn config_schema(&self) -> ROption<RString> { ... }
fn validate(&self, _: &PluginContext) -> RVec<Diagnostic> { ... }
}Expand description
The trait that all SPOA hub plugins must implement.
Plugins are loaded as shared libraries at runtime. The hub calls
init once after loading, then process for each SPOE message
that matches the plugin’s configured message names.
§Thread Safety
Send + Sync is required because plugin instances are shared
across connections via Arc. The process method takes &self,
so plugins must use interior mutability for any mutable state.
§Panic Safety
Use the define_plugin! macro to implement plugins — it wraps
process in catch_unwind to prevent panics from aborting the
hub process.
Required Methods§
Sourcefn init(&mut self, context: &PluginContext) -> RResult<(), RBoxError>
fn init(&mut self, context: &PluginContext) -> RResult<(), RBoxError>
Initialize the plugin. Called once after loading.
The context provides the plugin name and any configuration
parameters from the [plugins.params] TOML table. Use this
to set up resources (database connections, lookup tables, etc.).
Return RErr to abort plugin registration — the hub will log
the error and skip this plugin.
Sourcefn process(&self, message: &SpoeMessage) -> RResult<ProcessingResult, RBoxError>
fn process(&self, message: &SpoeMessage) -> RResult<ProcessingResult, RBoxError>
Process an SPOE message and return transaction variables.
Called for each SPOE message that matches this plugin’s
configured message names. The message contains pre-parsed
typed arguments and connection metadata (stream/frame IDs).
When this plugin depends on another, the upstream plugin’s
output variables are merged into message.args with their
namespace-prefixed names (e.g., "ja3.hash").
Variable names in the result should be unprefixed — the hub adds the plugin namespace automatically.
Sourcefn name<'_self>(&'_self self) -> RStr<'_self>
fn name<'_self>(&'_self self) -> RStr<'_self>
Human-readable plugin name used for logging and variable namespace prefixing.
Provided Methods§
Sourcefn config_schema(&self) -> ROption<RString>
fn config_schema(&self) -> ROption<RString>
Return a JSON Schema string to validate plugin configuration.
The hub calls this after new() and before init(). If
RSome(schema) is returned, the hub parses the string as
JSON Schema and validates the plugin’s [plugins.params]
against it. Validation failure prevents init() from being
called.
Return RNone (the default) to skip validation.
Sourcefn validate(&self, _: &PluginContext) -> RVec<Diagnostic>
fn validate(&self, _: &PluginContext) -> RVec<Diagnostic>
Deep validation of the plugin’s [plugins.params] subtree.
Called by the hub before init() (production mode) and by the
validator sidecar in --validate-socket mode. Returns a list
of Diagnostic findings; an empty list means “the plugin’s
configuration is valid as far as this plugin can tell.”
§Purity contract
validate() MUST be pure: no tokio tasks, no goroutines, no
network I/O, no file I/O beyond what the PluginContext
carries, no global state mutation. Plugins MAY use
process-internal caches scoped to plugin-instance lifetime.
Side effects in validation would surface in the validator
sidecar, which has no business contacting external services.
§Default behavior
The default impl returns an empty RVec, so existing plugins
built against the prior plugin-api version continue to work
unchanged. Plugins that want to surface line/column-precise
errors at admission time (and in the production hub’s startup
logs) override this method.
§Diagnostic.path
Plugins MUST leave the path field of returned diagnostics
empty. The hub fills it post-hoc with the file identity it
knows about. See Diagnostic for details.
See specs/004-validate-mode/ for the full design.