headless_lms_chatbot/
azure_datasources.rs1use 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 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}