Skip to main content

headless_lms_chatbot/
azure_datasources.rs

1use secrecy::ExposeSecret;
2use serde_json::json;
3
4use crate::prelude::*;
5
6pub const API_VERSION: &str = "2024-07-01";
7
8pub async fn does_azure_datasource_exist(
9    datasource_name: &str,
10    app_config: &ApplicationConfiguration,
11) -> ChatbotResult<bool> {
12    let azure_config = app_config.azure_configuration.as_ref().ok_or_else(|| {
13        chatbot_err!(
14            AzureRequestBuildError,
15            "Azure configuration is missing from the application configuration"
16        )
17    })?;
18
19    let search_config = azure_config.search_config.as_ref().ok_or_else(|| {
20        chatbot_err!(
21            AzureRequestBuildError,
22            "Azure search configuration is missing from the Azure configuration"
23        )
24    })?;
25    let mut url = search_config.search_endpoint.clone();
26    url.set_path(&format!("datasources('{}')", datasource_name));
27    url.set_query(Some(&format!("api-version={}", API_VERSION)));
28
29    let response = REQWEST_CLIENT
30        .get(url)
31        .header("Content-Type", "application/json")
32        .header("api-key", search_config.search_api_key.expose_secret())
33        .send()
34        .await?;
35
36    if response.status().is_success() {
37        Ok(true)
38    } else if response.status() == 404 {
39        Ok(false)
40    } else {
41        let status = response.status();
42        let error_text = response.text().await?;
43        Err(chatbot_err!(
44            FailedAzureResponse,
45            format!(
46                "Error checking if index exists. Status: {}. Error: {}",
47                status, error_text
48            )
49        ))
50    }
51}
52
53pub async fn create_azure_datasource(
54    datasource_name: &str,
55    container_name: &str,
56    app_config: &ApplicationConfiguration,
57) -> ChatbotResult<()> {
58    // Retrieve Azure configurations from the application configuration
59    let azure_config = app_config.azure_configuration.as_ref().ok_or_else(|| {
60        chatbot_err!(
61            AzureRequestBuildError,
62            "Azure configuration is missing from the application configuration"
63        )
64    })?;
65
66    let search_config = azure_config.search_config.as_ref().ok_or_else(|| {
67        chatbot_err!(
68            AzureRequestBuildError,
69            "Azure search configuration is missing from the Azure configuration"
70        )
71    })?;
72
73    let blob_storage_config = azure_config.blob_storage_config.as_ref().ok_or_else(|| {
74        chatbot_err!(
75            AzureRequestBuildError,
76            "Blob storage configuration is missing from the Azure configuration"
77        )
78    })?;
79
80    let connection_string = blob_storage_config.connection_string()?;
81
82    let mut url = search_config.search_endpoint.clone();
83    url.set_path(&format!("datasources/{}", datasource_name));
84    url.set_query(Some(&format!("api-version={}", API_VERSION)));
85
86    let datasource_definition = json!({
87        "name": datasource_name,
88        "type": "azureblob",
89        "container": {
90            "name": container_name,
91        },
92        "credentials": {
93            "connectionString": connection_string.expose_secret(),
94        },
95        "dataDeletionDetectionPolicy": {
96            "@odata.type": "#Microsoft.Azure.Search.NativeBlobSoftDeleteDeletionDetectionPolicy",
97        }
98    });
99
100    let response = REQWEST_CLIENT
101        .put(url)
102        .header("Content-Type", "application/json")
103        .header("api-key", search_config.search_api_key.expose_secret())
104        .json(&datasource_definition)
105        .send()
106        .await?;
107
108    if response.status().is_success() {
109        Ok(())
110    } else {
111        let status = response.status();
112        let error_text = response.text().await?;
113        Err(chatbot_err!(
114            FailedAzureResponse,
115            format!(
116                "Error creating datasource. Status: {}. Error: {}",
117                status, error_text
118            )
119        ))
120    }
121}