Skip to main content

drasi_lib/config/
snapshot.rs

1// Copyright 2025 The Drasi Authors.
2//
3// Licensed under the Apache License, Version 2.0 (the "License");
4// you may not use this file except in compliance with the License.
5// You may obtain a copy of the License at
6//
7//     http://www.apache.org/licenses/LICENSE-2.0
8//
9// Unless required by applicable law or agreed to in writing, software
10// distributed under the License is distributed on an "AS IS" BASIS,
11// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12// See the License for the specific language governing permissions and
13// limitations under the License.
14
15//! Configuration snapshot types for capturing point-in-time instance state.
16//!
17//! A [`ConfigurationSnapshot`] captures the full topology, status, and configuration
18//! properties of all components in a drasi-lib instance. Hosts can serialize this
19//! snapshot to store it, and later use it to reconstruct an equivalent instance.
20//!
21//! **Important:** Sources and reactions are trait objects — their properties are
22//! captured but they cannot be automatically deserialized back into instances.
23//! The host must supply the appropriate plugin factories to reconstruct them.
24
25use std::collections::HashMap;
26
27use serde::{Deserialize, Serialize};
28
29use crate::channels::ComponentStatus;
30use crate::component_graph::GraphEdge;
31use crate::config::schema::QueryConfig;
32
33/// A point-in-time snapshot of the full drasi-lib instance configuration.
34///
35/// Contains the topology (components and dependency edges), lifecycle status,
36/// and configuration properties of every source, query, and reaction.
37///
38/// # Serialization
39///
40/// This type implements `Serialize` and `Deserialize`, so it can be stored
41/// as JSON, YAML, or any serde-compatible format.
42///
43/// # Example
44///
45/// ```no_run
46/// # use drasi_lib::DrasiLib;
47/// # async fn example(core: &DrasiLib) -> Result<(), Box<dyn std::error::Error>> {
48/// let snapshot = core.snapshot_configuration().await?;
49/// let json = serde_json::to_string_pretty(&snapshot)?;
50/// std::fs::write("config-snapshot.json", &json)?;
51/// # Ok(())
52/// # }
53/// ```
54#[derive(Debug, Clone, Serialize, Deserialize)]
55pub struct ConfigurationSnapshot {
56    /// Unique identifier of the drasi-lib instance
57    pub instance_id: String,
58    /// ISO 8601 timestamp when the snapshot was captured
59    pub timestamp: String,
60    /// All source components with their configuration properties
61    pub sources: Vec<SourceSnapshot>,
62    /// All query components with their full query configurations
63    pub queries: Vec<QuerySnapshot>,
64    /// All reaction components with their configuration properties
65    pub reactions: Vec<ReactionSnapshot>,
66    /// Dependency edges between components (source→query, query→reaction)
67    pub edges: Vec<GraphEdge>,
68}
69
70/// Snapshot of a source component's configuration.
71#[derive(Debug, Clone, Serialize, Deserialize)]
72pub struct SourceSnapshot {
73    /// Source component identifier
74    pub id: String,
75    /// Plugin type identifier (e.g., "postgres", "http", "grpc")
76    pub source_type: String,
77    /// Lifecycle status at the time of snapshot
78    pub status: ComponentStatus,
79    /// Whether the source was configured to auto-start
80    pub auto_start: bool,
81    /// Configuration properties reported by the source plugin
82    pub properties: HashMap<String, serde_json::Value>,
83    /// Bootstrap provider configuration, if one is attached to this source
84    pub bootstrap_provider: Option<BootstrapSnapshot>,
85}
86
87/// Snapshot of a bootstrap provider's configuration.
88#[derive(Debug, Clone, Serialize, Deserialize)]
89pub struct BootstrapSnapshot {
90    /// Bootstrap provider kind (e.g., "postgres", "scriptfile", "noop")
91    pub kind: String,
92    /// Configuration properties for the bootstrap provider
93    pub properties: HashMap<String, serde_json::Value>,
94}
95
96/// Snapshot of a query component's configuration.
97#[derive(Debug, Clone, Serialize, Deserialize)]
98pub struct QuerySnapshot {
99    /// Query component identifier
100    pub id: String,
101    /// Full query configuration (query string, source subscriptions, joins, etc.)
102    pub config: QueryConfig,
103    /// Lifecycle status at the time of snapshot
104    pub status: ComponentStatus,
105}
106
107/// Snapshot of a reaction component's configuration.
108#[derive(Debug, Clone, Serialize, Deserialize)]
109pub struct ReactionSnapshot {
110    /// Reaction component identifier
111    pub id: String,
112    /// Plugin type identifier (e.g., "log", "http", "grpc")
113    pub reaction_type: String,
114    /// Lifecycle status at the time of snapshot
115    pub status: ComponentStatus,
116    /// Whether the reaction was configured to auto-start
117    pub auto_start: bool,
118    /// Query IDs this reaction subscribes to
119    pub queries: Vec<String>,
120    /// Configuration properties reported by the reaction plugin
121    pub properties: HashMap<String, serde_json::Value>,
122}