Skip to main content

redisctl_core/enterprise/
workflows.rs

1//! Higher-level Enterprise workflows that compose Layer 1 operations
2//!
3//! These workflows handle common patterns like:
4//! - Start operation, poll for completion, return result
5//! - Validate inputs before making API calls
6//! - Progress reporting for long-running operations
7
8use crate::enterprise::progress::{EnterpriseProgressCallback, poll_action};
9use crate::error::Result;
10use redis_enterprise::bdb::DatabaseUpgradeRequest;
11use redis_enterprise::{Database, EnterpriseClient};
12use std::time::Duration;
13
14/// Default timeout for Enterprise async operations (10 minutes)
15pub const DEFAULT_TIMEOUT: Duration = Duration::from_secs(600);
16
17/// Default polling interval for Enterprise operations (5 seconds)
18pub const DEFAULT_INTERVAL: Duration = Duration::from_secs(5);
19
20/// Upgrade a database's Redis version and wait for completion
21///
22/// This workflow:
23/// 1. Submits the upgrade request
24/// 2. Polls the returned action until completion
25/// 3. Returns the updated database
26///
27/// # Arguments
28///
29/// * `client` - The Enterprise API client
30/// * `bdb_uid` - The database UID to upgrade
31/// * `request` - The upgrade request parameters
32/// * `timeout` - Maximum time to wait for completion
33/// * `on_progress` - Optional callback for progress updates
34///
35/// # Example
36///
37/// ```rust,ignore
38/// use redisctl_core::enterprise::upgrade_database_and_wait;
39/// use redis_enterprise::DatabaseUpgradeRequest;
40/// use std::time::Duration;
41///
42/// let request = DatabaseUpgradeRequest::builder()
43///     .redis_version("7.2")
44///     .build();
45///
46/// let db = upgrade_database_and_wait(
47///     &client,
48///     1,
49///     &request,
50///     Duration::from_secs(600),
51///     None,
52/// ).await?;
53/// ```
54pub async fn upgrade_database_and_wait(
55    client: &EnterpriseClient,
56    bdb_uid: u32,
57    request: &DatabaseUpgradeRequest,
58    timeout: Duration,
59    on_progress: Option<EnterpriseProgressCallback>,
60) -> Result<Database> {
61    // Submit the upgrade request - returns the action with action_uid
62    let action = client
63        .databases()
64        .upgrade_redis_version(bdb_uid, request.clone())
65        .await?;
66
67    // Poll until completion
68    poll_action(
69        client,
70        &action.action_uid,
71        timeout,
72        DEFAULT_INTERVAL,
73        on_progress,
74    )
75    .await?;
76
77    // Fetch and return the updated database
78    let db = client.databases().get(bdb_uid).await?;
79    Ok(db)
80}
81
82/// Upgrade a database module and wait for completion
83///
84/// # Arguments
85///
86/// * `client` - The Enterprise API client
87/// * `bdb_uid` - The database UID
88/// * `module_name` - The module to upgrade (e.g., "search", "json")
89/// * `new_version` - The target module version
90/// * `timeout` - Maximum time to wait for completion
91/// * `on_progress` - Optional callback for progress updates
92pub async fn upgrade_module_and_wait(
93    client: &EnterpriseClient,
94    bdb_uid: u32,
95    module_name: &str,
96    new_version: &str,
97    timeout: Duration,
98    on_progress: Option<EnterpriseProgressCallback>,
99) -> Result<Database> {
100    // Submit the module upgrade request
101    let action = client
102        .databases()
103        .upgrade(bdb_uid, module_name, new_version)
104        .await?;
105
106    // Poll until completion
107    poll_action(
108        client,
109        &action.action_uid,
110        timeout,
111        DEFAULT_INTERVAL,
112        on_progress,
113    )
114    .await?;
115
116    // Fetch and return the updated database
117    let db = client.databases().get(bdb_uid).await?;
118    Ok(db)
119}
120
121/// Backup an Enterprise database and wait for completion
122///
123/// # Arguments
124///
125/// * `client` - The Enterprise API client
126/// * `bdb_uid` - The database UID to backup
127/// * `timeout` - Maximum time to wait for completion
128/// * `on_progress` - Optional callback for progress updates
129///
130/// # Returns
131///
132/// Returns `Ok(())` on success. The backup can be retrieved using the
133/// database's backup endpoints.
134pub async fn backup_database_and_wait(
135    client: &EnterpriseClient,
136    bdb_uid: u32,
137    timeout: Duration,
138    on_progress: Option<EnterpriseProgressCallback>,
139) -> Result<()> {
140    // Trigger backup
141    let response = client.databases().backup(bdb_uid).await?;
142
143    // Poll until completion if we got an action_uid
144    if let Some(action_uid) = response.action_uid {
145        poll_action(client, &action_uid, timeout, DEFAULT_INTERVAL, on_progress).await?;
146    }
147
148    Ok(())
149}
150
151/// Import data into an Enterprise database and wait for completion
152///
153/// WARNING: If `flush` is true, this will delete existing data before import!
154///
155/// # Arguments
156///
157/// * `client` - The Enterprise API client
158/// * `bdb_uid` - The database UID to import into
159/// * `import_location` - The location to import from (file path or URL)
160/// * `flush` - Whether to flush the database before import
161/// * `timeout` - Maximum time to wait for completion
162/// * `on_progress` - Optional callback for progress updates
163pub async fn import_database_and_wait(
164    client: &EnterpriseClient,
165    bdb_uid: u32,
166    import_location: &str,
167    flush: bool,
168    timeout: Duration,
169    on_progress: Option<EnterpriseProgressCallback>,
170) -> Result<()> {
171    // Start import
172    let response = client
173        .databases()
174        .import(bdb_uid, import_location, flush)
175        .await?;
176
177    // Poll until completion if we got an action_uid
178    if let Some(action_uid) = response.action_uid {
179        poll_action(client, &action_uid, timeout, DEFAULT_INTERVAL, on_progress).await?;
180    }
181
182    Ok(())
183}
184
185/// Flush all data from an Enterprise database and wait for completion
186///
187/// WARNING: This permanently deletes all data in the database!
188///
189/// # Arguments
190///
191/// * `client` - The Enterprise API client
192/// * `bdb_uid` - The database UID to flush
193/// * `timeout` - Maximum time to wait for completion
194/// * `on_progress` - Optional callback for progress updates
195pub async fn flush_database_and_wait(
196    client: &EnterpriseClient,
197    bdb_uid: u32,
198    timeout: Duration,
199    on_progress: Option<EnterpriseProgressCallback>,
200) -> Result<()> {
201    // Trigger flush
202    let response = client.databases().flush(bdb_uid).await?;
203
204    // Poll until completion
205    poll_action(
206        client,
207        &response.action_uid,
208        timeout,
209        DEFAULT_INTERVAL,
210        on_progress,
211    )
212    .await?;
213
214    Ok(())
215}