1use std::time::SystemTime;
8
9use tokio::sync::broadcast;
10
11#[derive(Debug, Clone)]
13pub struct EventSource {
14 sender: broadcast::Sender<BrokerEvent>,
15}
16
17#[derive(Debug, Clone)]
19pub struct BrokerEvent {
20 pub at: SystemTime,
22 pub kind: BrokerEventKind,
24}
25
26#[derive(Debug, Clone, PartialEq, Eq)]
28pub enum BrokerEventKind {
29 KeyRotated {
31 key_id: String,
33 new_version: u32,
35 },
36 BundleChanged {
38 trust_domain: String,
40 },
41 Revoked {
43 trust_domain: String,
45 id: String,
47 },
48}
49
50impl Default for EventSource {
51 fn default() -> Self {
52 Self::new()
53 }
54}
55
56impl EventSource {
57 #[must_use]
59 pub fn new() -> Self {
60 let (sender, _) = broadcast::channel(1024);
61 Self { sender }
62 }
63
64 #[must_use]
66 pub fn subscribe(&self) -> broadcast::Receiver<BrokerEvent> {
67 self.sender.subscribe()
68 }
69
70 pub fn key_rotated(&self, key_id: impl Into<String>, new_version: u32) {
72 self.publish(BrokerEventKind::KeyRotated {
73 key_id: key_id.into(),
74 new_version,
75 });
76 }
77
78 pub fn bundle_changed(&self, trust_domain: impl Into<String>) {
80 self.publish(BrokerEventKind::BundleChanged {
81 trust_domain: trust_domain.into(),
82 });
83 }
84
85 pub fn revoked(&self, trust_domain: impl Into<String>, id: impl Into<String>) {
87 self.publish(BrokerEventKind::Revoked {
88 trust_domain: trust_domain.into(),
89 id: id.into(),
90 });
91 }
92
93 fn publish(&self, kind: BrokerEventKind) {
94 let _receivers = self.sender.send(BrokerEvent {
95 at: SystemTime::now(),
96 kind,
97 });
98 }
99}
100
101#[cfg(test)]
102mod tests {
103 use super::*;
104
105 #[tokio::test]
106 async fn subscribers_receive_events() {
107 let source = EventSource::new();
108 let mut rx = source.subscribe();
109 source.key_rotated("app.key", 2);
110 let event = rx.recv().await.expect("event received");
111 assert_eq!(
112 event.kind,
113 BrokerEventKind::KeyRotated {
114 key_id: "app.key".to_string(),
115 new_version: 2,
116 }
117 );
118 }
119}