liminal_server/config/types.rs
1use std::net::SocketAddr;
2use std::path::PathBuf;
3use std::time::Duration;
4
5/// Declarative configuration for the standalone liminal server wrapper.
6#[derive(Debug, Clone, serde::Deserialize)]
7#[serde(deny_unknown_fields)]
8pub struct ServerConfig {
9 /// Socket address where the standalone server will listen for client traffic.
10 pub listen_address: SocketAddr,
11 /// Socket address where the health endpoint server will listen for probes.
12 pub health_listen_address: SocketAddr,
13 /// Maximum time to allow existing connections to drain during graceful shutdown.
14 pub drain_timeout_ms: u64,
15 /// Channel topology definitions declared by the operator.
16 pub channels: Vec<ChannelDef>,
17 /// Declarative routing rules that connect configured channels.
18 pub routing_rules: Vec<RoutingRuleDef>,
19 /// Optional filesystem location for durable server state.
20 pub persistence_path: Option<PathBuf>,
21 /// Optional beamr distribution cluster membership configuration.
22 pub cluster: Option<ClusterConfig>,
23}
24
25impl ServerConfig {
26 /// Returns the configured graceful-shutdown drain timeout.
27 #[must_use]
28 pub const fn drain_timeout(&self) -> Duration {
29 Duration::from_millis(self.drain_timeout_ms)
30 }
31}
32
33/// Declarative channel definition loaded from server configuration.
34#[derive(Debug, Clone, serde::Deserialize)]
35#[serde(deny_unknown_fields)]
36pub struct ChannelDef {
37 /// Unique channel name used by routing rules and operators.
38 pub name: String,
39 /// Schema reference used to validate messages for this channel.
40 pub schema_ref: String,
41 /// Whether this channel requires durable persistence.
42 pub durable: bool,
43}
44
45/// Declarative routing rule definition loaded from server configuration.
46#[derive(Debug, Clone, serde::Deserialize)]
47#[serde(deny_unknown_fields)]
48pub struct RoutingRuleDef {
49 /// Source channel name from which messages are routed.
50 pub source_channel: String,
51 /// Target channel name to which matching messages are routed.
52 pub target_channel: String,
53 /// Optional predicate expression that filters routed messages.
54 pub predicate: Option<String>,
55}
56
57/// Default beamr distribution handshake cookie, used when the operator does not
58/// configure one. Mirrors beamr's own [`beamr::distribution::DEFAULT_COOKIE`].
59pub const DEFAULT_COOKIE: &str = "beamr-cookie";
60
61/// Beamr distribution cluster configuration for standalone deployment.
62#[derive(Debug, Clone, serde::Deserialize)]
63#[serde(deny_unknown_fields)]
64pub struct ClusterConfig {
65 /// Unique node name advertised to the beamr distribution cluster.
66 pub node_name: String,
67 /// Socket address this node binds for inbound distribution links from peers.
68 ///
69 /// This is distinct from [`ServerConfig::listen_address`] (the client wire
70 /// port): a clustered node listens on two ports — one for clients, one for
71 /// peer distribution traffic.
72 pub listen_address: SocketAddr,
73 /// Seed node socket addresses used to join an existing cluster.
74 pub seed_nodes: Vec<SocketAddr>,
75 /// Shared distribution handshake cookie. Every node in a cluster MUST use the
76 /// same cookie or the OTP handshake is rejected. Defaults to
77 /// [`DEFAULT_COOKIE`] when omitted.
78 #[serde(default = "default_cookie")]
79 pub cookie: String,
80}
81
82fn default_cookie() -> String {
83 DEFAULT_COOKIE.to_owned()
84}