docbox_core/events/
mod.rs

1//! # Events
2//!
3//! Event publishing abstraction
4//!
5//! - [EventPublisherFactory] Factory for building a publisher based on the tenant
6//! - [SqsEventPublisherFactory] SQS based event notifications
7//! - [NoopEventPublisher] No-op publishing for tenants without event targets
8
9use docbox_database::models::tenant::Tenant;
10use docbox_database::models::{
11    document_box::{DocumentBox, WithScope},
12    file::File,
13    folder::Folder,
14    link::Link,
15};
16use serde::Serialize;
17
18pub mod mpsc;
19pub mod noop;
20pub mod sqs;
21
22use noop::NoopEventPublisher;
23use sqs::{SqsEventPublisherFactory, TenantSqsEventQueue};
24
25#[derive(Clone)]
26pub struct EventPublisherFactory {
27    /// Factory for creating SQS based event publishers
28    sqs: SqsEventPublisherFactory,
29}
30
31impl EventPublisherFactory {
32    pub fn new(sqs: SqsEventPublisherFactory) -> Self {
33        Self { sqs }
34    }
35
36    pub fn create_event_publisher(&self, tenant: &Tenant) -> TenantEventPublisher {
37        match tenant.event_queue_url.as_ref() {
38            Some(value) => {
39                let target = TenantSqsEventQueue {
40                    tenant_id: tenant.id,
41                    event_queue_url: value.clone(),
42                };
43
44                TenantEventPublisher::Sqs(self.sqs.create_event_publisher(target))
45            }
46            None => TenantEventPublisher::Noop(NoopEventPublisher),
47        }
48    }
49}
50
51/// Dynamic event publisher for a tenant
52#[derive(Clone)]
53pub enum TenantEventPublisher {
54    Sqs(sqs::SqsEventPublisher),
55    Noop(noop::NoopEventPublisher),
56    Mpsc(mpsc::MpscEventPublisher),
57}
58
59impl TenantEventPublisher {
60    pub fn publish_event(&self, event: TenantEventMessage) {
61        match self {
62            TenantEventPublisher::Sqs(inner) => inner.publish_event(event),
63            TenantEventPublisher::Noop(inner) => inner.publish_event(event),
64            TenantEventPublisher::Mpsc(inner) => inner.publish_event(event),
65        }
66    }
67}
68
69/// Event inner message type, containing the actual event data
70///
71/// i.e { "event": "DOCUMENT_BOX_CREATED", "data": { ...document box data }, "tenant_id": "xxxxx-xxxxx-xxxxx-xxxxx" }
72#[derive(Debug, Serialize)]
73#[serde(tag = "event", content = "data", rename_all = "SCREAMING_SNAKE_CASE")]
74pub enum TenantEventMessage {
75    // Creations (DOCUMENT_BOX_CREATED, ...etc)
76    DocumentBoxCreated(DocumentBox),
77    FileCreated(WithScope<File>),
78    FolderCreated(WithScope<Folder>),
79    LinkCreated(WithScope<Link>),
80
81    // Deletions
82    DocumentBoxDeleted(DocumentBox),
83    FileDeleted(WithScope<File>),
84    FolderDeleted(WithScope<Folder>),
85    LinkDeleted(WithScope<Link>),
86}
87
88/// Abstraction providing the ability to publish an event
89pub trait EventPublisher: Send + Sync + 'static {
90    /// Publish an event with the event publisher
91    fn publish_event(&self, event: TenantEventMessage);
92}