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) -> anyhow::Result<bool> {
12 let azure_config = app_config.azure_configuration.as_ref().ok_or_else(|| {
13 anyhow::anyhow!("Azure configuration is missing from the application configuration")
14 })?;
15
16 let search_config = azure_config.search_config.as_ref().ok_or_else(|| {
17 anyhow::anyhow!("Azure search configuration is missing from the Azure configuration")
18 })?;
19 let mut url = search_config.search_endpoint.clone();
20 url.set_path(&format!("datasources('{}')", datasource_name));
21 url.set_query(Some(&format!("api-version={}", API_VERSION)));
22
23 let response = REQWEST_CLIENT
24 .get(url)
25 .header("Content-Type", "application/json")
26 .header("api-key", search_config.search_api_key.expose_secret())
27 .send()
28 .await?;
29
30 if response.status().is_success() {
31 Ok(true)
32 } else if response.status() == 404 {
33 Ok(false)
34 } else {
35 let status = response.status();
36 let error_text = response.text().await?;
37 Err(anyhow::anyhow!(
38 "Error checking if index exists. Status: {}. Error: {}",
39 status,
40 error_text
41 ))
42 }
43}
44
45pub async fn create_azure_datasource(
46 datasource_name: &str,
47 container_name: &str,
48 app_config: &ApplicationConfiguration,
49) -> anyhow::Result<()> {
50 let azure_config = app_config.azure_configuration.as_ref().ok_or_else(|| {
52 anyhow::anyhow!("Azure configuration is missing from the application configuration")
53 })?;
54
55 let search_config = azure_config.search_config.as_ref().ok_or_else(|| {
56 anyhow::anyhow!("Azure search configuration is missing from the Azure configuration")
57 })?;
58
59 let blob_storage_config = azure_config.blob_storage_config.as_ref().ok_or_else(|| {
60 anyhow::anyhow!("Blob storage configuration is missing from the Azure configuration")
61 })?;
62
63 let connection_string = blob_storage_config.connection_string()?;
64
65 let mut url = search_config.search_endpoint.clone();
66 url.set_path(&format!("datasources/{}", datasource_name));
67 url.set_query(Some(&format!("api-version={}", API_VERSION)));
68
69 let datasource_definition = json!({
70 "name": datasource_name,
71 "type": "azureblob",
72 "container": {
73 "name": container_name,
74 },
75 "credentials": {
76 "connectionString": connection_string.expose_secret(),
77 },
78 "dataDeletionDetectionPolicy": {
79 "@odata.type": "#Microsoft.Azure.Search.NativeBlobSoftDeleteDeletionDetectionPolicy",
80 }
81 });
82
83 let response = REQWEST_CLIENT
84 .put(url)
85 .header("Content-Type", "application/json")
86 .header("api-key", search_config.search_api_key.expose_secret())
87 .json(&datasource_definition)
88 .send()
89 .await?;
90
91 if response.status().is_success() {
92 Ok(())
93 } else {
94 let status = response.status();
95 let error_text = response.text().await?;
96 Err(anyhow::anyhow!(
97 "Error creating datasource. Status: {}. Error: {}",
98 status,
99 error_text
100 ))
101 }
102}