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}