Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
24 changes: 1 addition & 23 deletions azure.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -12,26 +12,4 @@ services:
path: ./Dockerfile
context: ./
pipeline:
provider: github
hooks:
postprovision:
posix:
shell: sh
interactive: true
continueOnError: false
run: |
echo "
CONFIGURATION__AZURECOSMOSDB__ENDPOINT=\"$CONFIGURATION__AZURECOSMOSDB__ENDPOINT\"
CONFIGURATION__AZURECOSMOSDB__DATABASENAME=\"$CONFIGURATION__AZURECOSMOSDB__DATABASENAME\"
CONFIGURATION__AZURECOSMOSDB__CONTAINERNAME=\"$CONFIGURATION__AZURECOSMOSDB__CONTAINERNAME\"
" > ./src/.env
windows:
shell: pwsh
interactive: true
continueOnError: false
run: |
echo "
CONFIGURATION__AZURECOSMOSDB__ENDPOINT=""$env:CONFIGURATION__AZURECOSMOSDB__ENDPOINT""
CONFIGURATION__AZURECOSMOSDB__DATABASENAME=""$env:CONFIGURATION__AZURECOSMOSDB__DATABASENAME""
CONFIGURATION__AZURECOSMOSDB__CONTAINERNAME=""$env:CONFIGURATION__AZURECOSMOSDB__CONTAINERNAME""
" > ./src/.env
provider: github
5 changes: 4 additions & 1 deletion readme.md
Original file line number Diff line number Diff line change
Expand Up @@ -16,11 +16,14 @@ products:

This is a simple web application to illustrate common basic usage of Azure Cosmos DB for NoSQL with the Azure SDK for Rust.

> [!IMPORTANT]
> Local development is not supported in this template.

## Prerequisites

- [Docker](https://www.docker.com/)
- [Azure Developer CLI](https://aka.ms/azd-install)
- [Rust 1+](https://go.dev/dl/)
- [Rust 1.80 or later](https://go.dev/dl/)

## Quickstart

Expand Down
12 changes: 6 additions & 6 deletions src/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -7,14 +7,14 @@ name = "azure-cosmos-db-nosql-rust-quickstart"
edition = "2021"

[dependencies]
azure_data_cosmos = { git = "https://github.com/Azure/azure-sdk-for-rust.git" }
azure_identity = { git = "https://github.com/Azure/azure-sdk-for-rust.git" }
axum = "0.7.7"
azure_data_cosmos = "0.22.0"
azure_identity = "0.22.0"
dotenv = "0.15.0"
futures = "0.3.31"
serde = { version = "1.0.215", features = ["derive"] }
serde_json = "1.0.132"
tokio = { version = "1.41.1", features = ["full"] }
futures = "0.3.31"
socketioxide = "0.15.1"
axum = "0.7.7"
tokio = { version = "1.41.1", features = ["rt", "net", "rt-multi-thread", "macros"] }
tower = "0.5.1"
tower-http = { version = "0.5.0", features = ["cors", "fs"] }
tower-http = { version = "0.5.0", features = ["cors", "fs"] }
134 changes: 33 additions & 101 deletions src/app/cosmos.rs
Original file line number Diff line number Diff line change
@@ -1,29 +1,26 @@
use futures::StreamExt;
use serde_json;
use azure_data_cosmos::{CosmosClient, PartitionKey};
use azure_identity::DefaultAzureCredential;
use azure_data_cosmos::{CosmosClient, PartitionKey, Query};
use azure_identity::ManagedIdentityCredential;
use crate::item::Item;
use futures::stream::StreamExt;

pub async fn run<F>(
endpoint: String,
database_name: String,
container_name: String,
callback: F,
)
) -> Result<(), Box<dyn std::error::Error>>
where
F: Fn(String),
{
callback("Current Status:\tStarting...".to_string());

let credential = DefaultAzureCredential::new().unwrap();
// <create_client>
let credential = ManagedIdentityCredential::new()?;

let client = CosmosClient::new(&endpoint, credential, None)?;
// </create_client>

let client = match CosmosClient::new(&endpoint, credential, None) {
Ok(client) => client,
Err(e) => {
eprintln!("Error creating CosmosClient: {}", e);
return;
}
};
callback("Client created".to_string());

let database = client.database_client(&database_name);
Expand All @@ -41,28 +38,12 @@ where
price: 850.00,
clearance: false,
};

let partition_key = PartitionKey::from(item.category.clone());

container.upsert_item(partition_key, item.clone(), None).await?;

let upsert_response = container.upsert_item(partition_key, item, None).await;

match upsert_response {
Ok(r) => {
let deserialize_response = r.deserialize_body().await;
match deserialize_response {
Ok(i) => {
let upserted_item = i.unwrap();
callback(format!("Upserted item:\t{}", upserted_item.id));
},
Err(e) => {
eprintln!("Error deserializing response: {}", e);
},
}
},
Err(e) => {
eprintln!("Error upserting item: {}", e);
},
}
callback(format!("Upserted item:\t{}", item.id));
}

{
Expand All @@ -77,90 +58,41 @@ where

let partition_key = PartitionKey::from(item.category.clone());

let upsert_response = container.upsert_item(partition_key, item, None).await;

match upsert_response {
Ok(r) => {
let deserialize_response = r.deserialize_body().await;
match deserialize_response {
Ok(i) => {
let upserted_item = i.unwrap();
callback(format!("Upserted item:\t{}", upserted_item.id));
},
Err(e) => {
eprintln!("Error deserializing response: {}", e);
},
}
},
Err(e) => {
eprintln!("Error upserting item: {}", e);
},
}
container.upsert_item(partition_key, item.clone(), None).await?;

callback(format!("Upserted item:\t{}", item.id));
}

{
let item_id = "aaaaaaaa-0000-1111-2222-bbbbbbbbbbbb";
let item_partition_key = "gear-surf-surfboards";

let read_response = container.read_item::<Item>(item_partition_key, item_id, None).await;

match read_response {
Ok(r) => {
let deserialize_response = r.deserialize_body().await;
match deserialize_response {
Ok(i) => {
let read_item = i.unwrap();
callback(format!("Read item:\t{}\t{}", read_item.id, read_item.category));
},
Err(e) => {
eprintln!("Error deserializing response: {}", e);
},
}
},
Err(e) => {
eprintln!("Error reading item: {}", e);
},
}
let response = container.read_item(item_partition_key, item_id, None).await?;

let item: Item = response.into_json_body().await?;

callback(format!("Read item:\t{}\t{}", item.id, item.category));
}

{
let item_partition_key = "gear-surf-surfboards";

let partition_key = PartitionKey::from(item_partition_key);
let query = Query::from("SELECT * FROM c WHERE c.category = @category")
.with_parameter("@category", item_partition_key)?;

let query = format!("SELECT * FROM c WHERE c.category = '{}'", item_partition_key);

let page_response = container.query_items::<Item>(&query, partition_key, None);
let mut pager = container.query_items::<Item>(query, item_partition_key, None)?;

callback("Run query:".to_string());
match page_response {
Ok(mut page) => {
while let Some(item) = page.next().await {
match item {
Ok(i) => {
let deserialize_response = i.deserialize_body().await;
match deserialize_response {
Ok(page) => {
for item in page.items {
callback(serde_json::to_string_pretty(&item).unwrap());
}
},
Err(e) => {
eprintln!("Error deserializing item: {}", e);
},
}
},
Err(e) => {
eprintln!("Error querying item: {}", e);
},
}
}
},
Err(e) => {
eprintln!("Error querying items: {}", e);
},

while let Some(page_response) = pager.next().await {
let page = page_response?.into_body().await?;
for item in page.items {
callback(serde_json::to_string_pretty(&item).unwrap());
}
}
}

callback("Current Status:\tStopping...".to_string());
}

Ok(())
}
7 changes: 5 additions & 2 deletions src/app/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -31,12 +31,15 @@ async fn main() -> Result<(), Box<dyn std::error::Error>> {
};

tokio::spawn(async move {
cosmos::run(
match cosmos::run(
std::env::var("CONFIGURATION__AZURECOSMOSDB__ENDPOINT").expect("Missing CONFIGURATION__AZURECOSMOSDB__ENDPOINT environment variable."),
std::env::var("CONFIGURATION__AZURECOSMOSDB__DATABASENAME").expect("Missing CONFIGURATION__AZURECOSMOSDB__DATABASENAME environment variable."),
std::env::var("CONFIGURATION__AZURECOSMOSDB__CONTAINERNAME").expect("Missing CONFIGURATION__AZURECOSMOSDB__CONTAINERNAME environment variable."),
handle_message,
).await;
).await {
Ok(_) => (),
Err(e) => println!("Error running Azure Cosmos DB for NoSQL script: {:?}", e),
}
});
});
});
Expand Down