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