From 20b167364b46749241c09bde03d692d345bc7e6c Mon Sep 17 00:00:00 2001 From: Francesco Cogno Date: Thu, 14 May 2020 13:45:58 +0200 Subject: [PATCH] Add support for CosmosDB `Get Partition Key Ranges` REST API (#269) --- README.md | 4 +- azure_sdk_cosmos/Cargo.toml | 2 +- azure_sdk_cosmos/examples/key_ranges00.rs | 26 ++ azure_sdk_cosmos/src/clients/client.rs | 3 + .../src/clients/collection_client.rs | 4 + azure_sdk_cosmos/src/from_headers.rs | 7 + azure_sdk_cosmos/src/lib.rs | 3 + azure_sdk_cosmos/src/partition_key_range.rs | 21 ++ .../get_partition_key_ranges_builder.json | 64 +++++ .../get_partition_key_ranges_builder.rs | 236 ++++++++++++++++++ azure_sdk_cosmos/src/requests/mod.rs | 2 + .../get_partition_key_ranges_response.rs | 75 ++++++ azure_sdk_cosmos/src/responses/mod.rs | 2 + azure_sdk_cosmos/tests/cosmos_collection.rs | 7 + 14 files changed, 453 insertions(+), 3 deletions(-) create mode 100644 azure_sdk_cosmos/examples/key_ranges00.rs create mode 100644 azure_sdk_cosmos/src/partition_key_range.rs create mode 100644 azure_sdk_cosmos/src/requests/get_partition_key_ranges_builder.json create mode 100644 azure_sdk_cosmos/src/requests/get_partition_key_ranges_builder.rs create mode 100644 azure_sdk_cosmos/src/responses/get_partition_key_ranges_response.rs diff --git a/README.md b/README.md index 3881134d4..057485c32 100644 --- a/README.md +++ b/README.md @@ -5,7 +5,7 @@ [![Build Status](https://travis-ci.org/MindFlavor/AzureSDKForRust.svg?branch=master)](https://travis-ci.org/MindFlavor/AzureSDKForRust) [![Coverage Status](https://coveralls.io/repos/MindFlavor/AzureSDKForRust/badge.svg?branch=master&service=github)](https://coveralls.io/github/MindFlavor/AzureSDKForRust?branch=master) ![stability-unstable](https://img.shields.io/badge/stability-unstable-yellow.svg) -[![tag](https://img.shields.io/github/tag/mindflavor/AzureSDKForRust.svg)](https://github.com/MindFlavor/AzureSDKForRust/tree/core_0.43.2) [![release](https://img.shields.io/github/release/mindflavor/AzureSDKForRust.svg)](https://github.com/MindFlavor/AzureSDKForRust/releases/tag/core_0.43.2) [![commitssince](https://img.shields.io/github/commits-since/mindflavor/AzureSDKForRust/core_0.43.2)](https://github.com/MindFlavor/AzureSDKForRust/commits/master) +[![tag](https://img.shields.io/github/tag/mindflavor/AzureSDKForRust.svg)](https://github.com/MindFlavor/AzureSDKForRust/tree/cosmos_0.42.4) [![release](https://img.shields.io/github/release/mindflavor/AzureSDKForRust.svg)](https://github.com/MindFlavor/AzureSDKForRust/releases/tag/cosmos_0.42.4) [![commitssince](https://img.shields.io/github/commits-since/mindflavor/AzureSDKForRust/cosmos_0.42.4)](https://github.com/MindFlavor/AzureSDKForRust/commits/master) [![GitHub contributors](https://img.shields.io/github/contributors/MindFlavor/AzureSDKForRust.svg)](https://github.com/MindFlavor/AzureSDKForRust/graphs/contributors) @@ -13,7 +13,7 @@ Crate | Docs | Crates.io | Downloads | Downloads@Latest | -- | -- | -- | -- | -- | [azure_sdk_auth_aad](https://github.com/MindFlavor/AzureSDKForRust/tree/master/azure_sdk_auth_aad) | [![docs](https://docs.rs/azure_sdk_auth_aad/badge.svg)](https://docs.rs/azure_sdk_auth_aad/0.42.2/azure_sdk_auth_aad) | [![Crate](https://img.shields.io/crates/v/azure_sdk_auth_aad.svg)](https://crates.io/crates/azure_sdk_auth_aad) | [![cratedown](https://img.shields.io/crates/d/azure_sdk_auth_aad.svg)](https://crates.io/crates/azure_sdk_auth_aad) | [![cratelastdown](https://img.shields.io/crates/dv/azure_sdk_auth_aad.svg)](https://crates.io/crates/azure_sdk_auth_aad) [azure_sdk_core](https://github.com/MindFlavor/AzureSDKForRust/tree/master/azure_sdk_core) | [![docs](https://docs.rs/azure_sdk_core/badge.svg)](https://docs.rs/azure_sdk_core/0.43.2/azure_sdk_core) | [![Crate](https://img.shields.io/crates/v/azure_sdk_core.svg)](https://crates.io/crates/azure_sdk_core) | [![cratedown](https://img.shields.io/crates/d/azure_sdk_core.svg)](https://crates.io/crates/azure_sdk_core) | [![cratelastdown](https://img.shields.io/crates/dv/azure_sdk_core.svg)](https://crates.io/crates/azure_sdk_core) -[azure_sdk_cosmos](https://github.com/MindFlavor/AzureSDKForRust/tree/master/azure_sdk_cosmos) | [![docs](https://docs.rs/azure_sdk_cosmos/badge.svg)](https://docs.rs/azure_sdk_cosmos/0.42.3/azure_sdk_cosmos) | [![Crate](https://img.shields.io/crates/v/azure_sdk_cosmos.svg)](https://crates.io/crates/azure_sdk_cosmos) | [![cratedown](https://img.shields.io/crates/d/azure_sdk_cosmos.svg)](https://crates.io/crates/azure_sdk_cosmos) | [![cratelastdown](https://img.shields.io/crates/dv/azure_sdk_cosmos.svg)](https://crates.io/crates/azure_sdk_cosmos) +[azure_sdk_cosmos](https://github.com/MindFlavor/AzureSDKForRust/tree/master/azure_sdk_cosmos) | [![docs](https://docs.rs/azure_sdk_cosmos/badge.svg)](https://docs.rs/azure_sdk_cosmos/0.42.4/azure_sdk_cosmos) | [![Crate](https://img.shields.io/crates/v/azure_sdk_cosmos.svg)](https://crates.io/crates/azure_sdk_cosmos) | [![cratedown](https://img.shields.io/crates/d/azure_sdk_cosmos.svg)](https://crates.io/crates/azure_sdk_cosmos) | [![cratelastdown](https://img.shields.io/crates/dv/azure_sdk_cosmos.svg)](https://crates.io/crates/azure_sdk_cosmos) [azure_sdk_service_bus](https://github.com/MindFlavor/AzureSDKForRust/tree/master/azure_sdk_service_bus) | [![docs](https://docs.rs/azure_sdk_service_bus/badge.svg)](https://docs.rs/azure_sdk_service_bus/0.44.0/azure_sdk_service_bus) | [![Crate](https://img.shields.io/crates/v/azure_sdk_service_bus.svg)](https://crates.io/crates/azure_sdk_service_bus) | [![cratedown](https://img.shields.io/crates/d/azure_sdk_service_bus.svg)](https://crates.io/crates/azure_sdk_service_bus) | [![cratelastdown](https://img.shields.io/crates/dv/azure_sdk_service_bus.svg)](https://crates.io/crates/azure_sdk_service_bus) [azure_sdk_storage_account](https://github.com/MindFlavor/AzureSDKForRust/tree/master/azure_sdk_storage_account) | [![docs](https://docs.rs/azure_sdk_storage_account/badge.svg)](https://docs.rs/azure_sdk_storage_account/0.40.4/azure_sdk_storage_account) | [![Crate](https://img.shields.io/crates/v/azure_sdk_storage_account.svg)](https://crates.io/crates/azure_sdk_storage_account) | [![cratedown](https://img.shields.io/crates/d/azure_sdk_storage_account.svg)](https://crates.io/crates/azure_sdk_storage_account) | [![cratelastdown](https://img.shields.io/crates/dv/azure_sdk_storage_account.svg)](https://crates.io/crates/azure_sdk_storage_account) [azure_sdk_storage_blob](https://github.com/MindFlavor/AzureSDKForRust/tree/master/azure_sdk_storage_blob) | [![docs](https://docs.rs/azure_sdk_storage_blob/badge.svg)](https://docs.rs/azure_sdk_storage_blob/0.43.2/azure_sdk_storage_blob) | [![Crate](https://img.shields.io/crates/v/azure_sdk_storage_blob.svg)](https://crates.io/crates/azure_sdk_storage_blob) | [![cratedown](https://img.shields.io/crates/d/azure_sdk_storage_blob.svg)](https://crates.io/crates/azure_sdk_storage_blob) | [![cratelastdown](https://img.shields.io/crates/dv/azure_sdk_storage_blob.svg)](https://crates.io/crates/azure_sdk_storage_blob) diff --git a/azure_sdk_cosmos/Cargo.toml b/azure_sdk_cosmos/Cargo.toml index f9b45b9d5..68b97cb6a 100644 --- a/azure_sdk_cosmos/Cargo.toml +++ b/azure_sdk_cosmos/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "azure_sdk_cosmos" -version = "0.42.3" +version = "0.42.4" description = "Rust wrappers around Microsoft Azure REST APIs - Azure Cosmos DB crate" readme = "README.md" authors = ["Francesco Cogno ", "Max Gortman "] diff --git a/azure_sdk_cosmos/examples/key_ranges00.rs b/azure_sdk_cosmos/examples/key_ranges00.rs new file mode 100644 index 000000000..a1df4d8ac --- /dev/null +++ b/azure_sdk_cosmos/examples/key_ranges00.rs @@ -0,0 +1,26 @@ +use azure_sdk_cosmos::prelude::*; +use std::error::Error; + +#[tokio::main] +async fn main() -> Result<(), Box> { + let database = std::env::args() + .nth(1) + .expect("please specify database name as first command line parameter"); + let collection = std::env::args() + .nth(2) + .expect("please specify collection name as second command line parameter"); + + let master_key = + std::env::var("COSMOS_MASTER_KEY").expect("Set env variable COSMOS_MASTER_KEY first!"); + let account = std::env::var("COSMOS_ACCOUNT").expect("Set env variable COSMOS_ACCOUNT first!"); + + let authorization_token = AuthorizationToken::new_master(&master_key)?; + let client = ClientBuilder::new(account, authorization_token.clone())?; + let client = client.with_database(&database); + let client = client.with_collection(&collection); + + let resp = client.get_partition_key_ranges().execute().await?; + println!("resp == {:#?}", resp); + + Ok(()) +} diff --git a/azure_sdk_cosmos/src/clients/client.rs b/azure_sdk_cosmos/src/clients/client.rs index fd0b1ab03..9d7e8599d 100644 --- a/azure_sdk_cosmos/src/clients/client.rs +++ b/azure_sdk_cosmos/src/clients/client.rs @@ -31,6 +31,7 @@ pub(crate) enum ResourceType { Users, Permissions, Attachments, + PartitionKeyRanges, } pub trait CosmosUriBuilder { @@ -332,6 +333,7 @@ fn string_to_sign( ResourceType::Users => "users", ResourceType::Permissions => "permissions", ResourceType::Attachments => "attachments", + ResourceType::PartitionKeyRanges => "pkranges", }, resource_link, time.to_lowercase() @@ -347,6 +349,7 @@ fn generate_resource_link(u: &str) -> &str { "users", "permissions", "attachments", + "pkranges", ]; // store the element only if it does not end with dbs, colls or docs diff --git a/azure_sdk_cosmos/src/clients/collection_client.rs b/azure_sdk_cosmos/src/clients/collection_client.rs index 8fb3bec00..f122b1803 100644 --- a/azure_sdk_cosmos/src/clients/collection_client.rs +++ b/azure_sdk_cosmos/src/clients/collection_client.rs @@ -101,6 +101,10 @@ where requests::ListStoredProceduresBuilder::new(self) } + fn get_partition_key_ranges(&self) -> requests::GetPartitionKeyRangesBuilder<'_, '_, CUB> { + requests::GetPartitionKeyRangesBuilder::new(self) + } + fn with_document<'c>( &'c self, document_name: &'c dyn DocumentName, diff --git a/azure_sdk_cosmos/src/from_headers.rs b/azure_sdk_cosmos/src/from_headers.rs index 60f411c49..df5488d36 100644 --- a/azure_sdk_cosmos/src/from_headers.rs +++ b/azure_sdk_cosmos/src/from_headers.rs @@ -244,6 +244,13 @@ pub(crate) fn schema_version_from_headers(headers: &HeaderMap) -> Result<&str, A .to_str()?) } +pub(crate) fn server_from_headers(headers: &HeaderMap) -> Result<&str, AzureError> { + Ok(headers + .get(hyper::header::SERVER) + .ok_or_else(|| AzureError::HeaderNotFound(hyper::header::SERVER.to_string()))? + .to_str()?) +} + pub(crate) fn service_version_from_headers(headers: &HeaderMap) -> Result<&str, AzureError> { Ok(headers .get(HEADER_SERVICE_VERSION) diff --git a/azure_sdk_cosmos/src/lib.rs b/azure_sdk_cosmos/src/lib.rs index ae2e59af3..0217c1bbd 100644 --- a/azure_sdk_cosmos/src/lib.rs +++ b/azure_sdk_cosmos/src/lib.rs @@ -20,6 +20,7 @@ pub(crate) mod from_headers; mod headers; mod indexing_directive; pub mod offer; +mod partition_key_range; mod partition_keys; mod permission; mod permission_resource; @@ -43,6 +44,7 @@ pub use self::document::{Document, DocumentName}; pub use self::document_attributes::DocumentAttributes; pub use self::indexing_directive::IndexingDirective; pub use self::offer::Offer; +pub use self::partition_key_range::PartitionKeyRange; pub use self::permission::{Permission, PermissionMode, PermissionName}; pub use self::permission_resource::PermissionResource; pub use self::permission_token::PermissionToken; @@ -609,6 +611,7 @@ where stored_procedure_name: &'c dyn StoredProcedureName, ) -> StoredProcedureClient<'c, CUB>; fn list_stored_procedures(&self) -> requests::ListStoredProceduresBuilder<'_, CUB>; + fn get_partition_key_ranges(&self) -> requests::GetPartitionKeyRangesBuilder<'_, '_, CUB>; fn with_document<'c>( &'c self, document_name: &'c dyn DocumentName, diff --git a/azure_sdk_cosmos/src/partition_key_range.rs b/azure_sdk_cosmos/src/partition_key_range.rs new file mode 100644 index 000000000..08064ce5f --- /dev/null +++ b/azure_sdk_cosmos/src/partition_key_range.rs @@ -0,0 +1,21 @@ +#[derive(Debug, PartialEq, PartialOrd, Clone, Deserialize)] +pub struct PartitionKeyRange { + #[serde(rename = "_rid")] + pub rid: String, + pub id: String, + #[serde(rename = "_etag")] + pub etag: String, + #[serde(rename = "minInclusive")] + pub min_exclusive: String, + #[serde(rename = "maxExclusive")] + pub max_exclusive: String, + #[serde(rename = "ridPrefix")] + pub rid_prefix: u64, + pub _self: String, + #[serde(rename = "throughputFraction")] + pub throughput_fraction: u64, + pub status: String, + // TODO: parents + #[serde(rename = "_ts")] + pub ts: u64, +} diff --git a/azure_sdk_cosmos/src/requests/get_partition_key_ranges_builder.json b/azure_sdk_cosmos/src/requests/get_partition_key_ranges_builder.json new file mode 100644 index 000000000..fc92b989b --- /dev/null +++ b/azure_sdk_cosmos/src/requests/get_partition_key_ranges_builder.json @@ -0,0 +1,64 @@ +{ + "name": "GetPartitionKeyRangesBuilder", + "derive": "Debug, Clone", + "uses": [ + "crate::clients::{CollectionClient, CosmosUriBuilder, ResourceType}", + "crate::prelude::*", + "crate::responses::*", + "crate::CollectionClientRequired", + "azure_sdk_core::errors::{check_status_extract_headers_and_body, AzureError}", + "azure_sdk_core::modify_conditions::IfMatchCondition", + "azure_sdk_core::prelude::*", + "azure_sdk_core::{IfMatchConditionOption, IfMatchConditionSupport}", + "chrono::{DateTime, Utc}", + "hyper::StatusCode", + "std::convert::TryInto" + ], + "inline": true, + "extra_types": [ "'a", "'b", "CUB" ], + "extra_wheres": ["CUB: CosmosUriBuilder" ], + "constructor_fields": [ + { + "name": "collection_client", + "field_type": "&'a CollectionClient<'a, CUB>", + "trait_get": "CollectionClientRequired<'a, CUB>" + } + ], + "fields": [ + { + "name": "if_match_condition", + "field_type": "IfMatchCondition<'b>", + "optional": true, + "trait_get": "IfMatchConditionOption<'b>", + "trait_set": "IfMatchConditionSupport<'b>" + }, + { + "name": "if_modified_since", + "field_type": "&'b DateTime", + "optional": true, + "trait_get": "IfModifiedSinceOption<'b>", + "trait_set": "IfModifiedSinceSupport<'b>" + }, + { + "name": "user_agent", + "field_type": "&'b str", + "optional": true, + "trait_get": "UserAgentOption<'b>", + "trait_set": "UserAgentSupport<'b>" + }, + { + "name": "activity_id", + "field_type": "&'b str", + "optional": true, + "trait_get": "ActivityIdOption<'b>", + "trait_set": "ActivityIdSupport<'b>" + }, + { + "name": "consistency_level", + "field_type": "ConsistencyLevel<'b>", + "optional": true, + "trait_get": "ConsistencyLevelOption<'b>", + "trait_set": "ConsistencyLevelSupport<'b>" + } + ] +} diff --git a/azure_sdk_cosmos/src/requests/get_partition_key_ranges_builder.rs b/azure_sdk_cosmos/src/requests/get_partition_key_ranges_builder.rs new file mode 100644 index 000000000..e9951a9fe --- /dev/null +++ b/azure_sdk_cosmos/src/requests/get_partition_key_ranges_builder.rs @@ -0,0 +1,236 @@ +use crate::clients::{CollectionClient, CosmosUriBuilder, ResourceType}; +use crate::prelude::*; +use crate::responses::*; +use crate::CollectionClientRequired; +use azure_sdk_core::errors::{check_status_extract_headers_and_body, AzureError}; +use azure_sdk_core::modify_conditions::IfMatchCondition; +use azure_sdk_core::prelude::*; +use azure_sdk_core::{IfMatchConditionOption, IfMatchConditionSupport}; +use chrono::{DateTime, Utc}; +use hyper::StatusCode; +use std::convert::TryInto; + +#[derive(Debug, Clone)] +pub struct GetPartitionKeyRangesBuilder<'a, 'b, CUB> +where + CUB: CosmosUriBuilder, +{ + collection_client: &'a CollectionClient<'a, CUB>, + if_match_condition: Option>, + if_modified_since: Option<&'b DateTime>, + user_agent: Option<&'b str>, + activity_id: Option<&'b str>, + consistency_level: Option>, +} + +impl<'a, 'b, CUB> GetPartitionKeyRangesBuilder<'a, 'b, CUB> +where + CUB: CosmosUriBuilder, +{ + #[inline] + pub(crate) fn new( + collection_client: &'a CollectionClient<'a, CUB>, + ) -> GetPartitionKeyRangesBuilder<'a, 'b, CUB> { + GetPartitionKeyRangesBuilder { + collection_client, + if_match_condition: None, + if_modified_since: None, + user_agent: None, + activity_id: None, + consistency_level: None, + } + } +} + +impl<'a, 'b, CUB> CollectionClientRequired<'a, CUB> for GetPartitionKeyRangesBuilder<'a, 'b, CUB> +where + CUB: CosmosUriBuilder, +{ + #[inline] + fn collection_client(&self) -> &'a CollectionClient<'a, CUB> { + self.collection_client + } +} + +//get mandatory no traits methods + +//set mandatory no traits methods +impl<'a, 'b, CUB> IfMatchConditionOption<'b> for GetPartitionKeyRangesBuilder<'a, 'b, CUB> +where + CUB: CosmosUriBuilder, +{ + #[inline] + fn if_match_condition(&self) -> Option> { + self.if_match_condition + } +} + +impl<'a, 'b, CUB> IfModifiedSinceOption<'b> for GetPartitionKeyRangesBuilder<'a, 'b, CUB> +where + CUB: CosmosUriBuilder, +{ + #[inline] + fn if_modified_since(&self) -> Option<&'b DateTime> { + self.if_modified_since + } +} + +impl<'a, 'b, CUB> UserAgentOption<'b> for GetPartitionKeyRangesBuilder<'a, 'b, CUB> +where + CUB: CosmosUriBuilder, +{ + #[inline] + fn user_agent(&self) -> Option<&'b str> { + self.user_agent + } +} + +impl<'a, 'b, CUB> ActivityIdOption<'b> for GetPartitionKeyRangesBuilder<'a, 'b, CUB> +where + CUB: CosmosUriBuilder, +{ + #[inline] + fn activity_id(&self) -> Option<&'b str> { + self.activity_id + } +} + +impl<'a, 'b, CUB> ConsistencyLevelOption<'b> for GetPartitionKeyRangesBuilder<'a, 'b, CUB> +where + CUB: CosmosUriBuilder, +{ + #[inline] + fn consistency_level(&self) -> Option> { + self.consistency_level.clone() + } +} + +impl<'a, 'b, CUB> IfMatchConditionSupport<'b> for GetPartitionKeyRangesBuilder<'a, 'b, CUB> +where + CUB: CosmosUriBuilder, +{ + type O = GetPartitionKeyRangesBuilder<'a, 'b, CUB>; + + #[inline] + fn with_if_match_condition(self, if_match_condition: IfMatchCondition<'b>) -> Self::O { + GetPartitionKeyRangesBuilder { + collection_client: self.collection_client, + if_match_condition: Some(if_match_condition), + if_modified_since: self.if_modified_since, + user_agent: self.user_agent, + activity_id: self.activity_id, + consistency_level: self.consistency_level, + } + } +} + +impl<'a, 'b, CUB> IfModifiedSinceSupport<'b> for GetPartitionKeyRangesBuilder<'a, 'b, CUB> +where + CUB: CosmosUriBuilder, +{ + type O = GetPartitionKeyRangesBuilder<'a, 'b, CUB>; + + #[inline] + fn with_if_modified_since(self, if_modified_since: &'b DateTime) -> Self::O { + GetPartitionKeyRangesBuilder { + collection_client: self.collection_client, + if_match_condition: self.if_match_condition, + if_modified_since: Some(if_modified_since), + user_agent: self.user_agent, + activity_id: self.activity_id, + consistency_level: self.consistency_level, + } + } +} + +impl<'a, 'b, CUB> UserAgentSupport<'b> for GetPartitionKeyRangesBuilder<'a, 'b, CUB> +where + CUB: CosmosUriBuilder, +{ + type O = GetPartitionKeyRangesBuilder<'a, 'b, CUB>; + + #[inline] + fn with_user_agent(self, user_agent: &'b str) -> Self::O { + GetPartitionKeyRangesBuilder { + collection_client: self.collection_client, + if_match_condition: self.if_match_condition, + if_modified_since: self.if_modified_since, + user_agent: Some(user_agent), + activity_id: self.activity_id, + consistency_level: self.consistency_level, + } + } +} + +impl<'a, 'b, CUB> ActivityIdSupport<'b> for GetPartitionKeyRangesBuilder<'a, 'b, CUB> +where + CUB: CosmosUriBuilder, +{ + type O = GetPartitionKeyRangesBuilder<'a, 'b, CUB>; + + #[inline] + fn with_activity_id(self, activity_id: &'b str) -> Self::O { + GetPartitionKeyRangesBuilder { + collection_client: self.collection_client, + if_match_condition: self.if_match_condition, + if_modified_since: self.if_modified_since, + user_agent: self.user_agent, + activity_id: Some(activity_id), + consistency_level: self.consistency_level, + } + } +} + +impl<'a, 'b, CUB> ConsistencyLevelSupport<'b> for GetPartitionKeyRangesBuilder<'a, 'b, CUB> +where + CUB: CosmosUriBuilder, +{ + type O = GetPartitionKeyRangesBuilder<'a, 'b, CUB>; + + #[inline] + fn with_consistency_level(self, consistency_level: ConsistencyLevel<'b>) -> Self::O { + GetPartitionKeyRangesBuilder { + collection_client: self.collection_client, + if_match_condition: self.if_match_condition, + if_modified_since: self.if_modified_since, + user_agent: self.user_agent, + activity_id: self.activity_id, + consistency_level: Some(consistency_level), + } + } +} + +// methods callable only when every mandatory field has been filled +impl<'a, 'b, CUB> GetPartitionKeyRangesBuilder<'a, 'b, CUB> +where + CUB: CosmosUriBuilder, +{ + pub async fn execute(&self) -> Result { + trace!("GetPartitionKeyRangesBuilder::execute called"); + + let request = self.collection_client().main_client().prepare_request( + &format!( + "dbs/{}/colls/{}/pkranges", + self.collection_client.database_name().name(), + self.collection_client.collection_name().name() + ), + hyper::Method::GET, + ResourceType::PartitionKeyRanges, + ); + + let request = request.header(hyper::header::CONTENT_LENGTH, "0"); + let request = IfMatchConditionOption::add_header(self, request); + let request = IfModifiedSinceOption::add_header(self, request); + let request = UserAgentOption::add_header(self, request); + let request = ActivityIdOption::add_header(self, request); + let request = ConsistencyLevelOption::add_header(self, request); + + let request = request.body(hyper::Body::empty())?; + + let future_response = self.collection_client().hyper_client().request(request); + let (headers, body) = + check_status_extract_headers_and_body(future_response, StatusCode::OK).await?; + + Ok((&headers, &body as &[u8]).try_into()?) + } +} diff --git a/azure_sdk_cosmos/src/requests/mod.rs b/azure_sdk_cosmos/src/requests/mod.rs index 69da50691..b91128cf5 100644 --- a/azure_sdk_cosmos/src/requests/mod.rs +++ b/azure_sdk_cosmos/src/requests/mod.rs @@ -18,6 +18,7 @@ mod get_attachment_builder; mod get_collection_builder; mod get_database_builder; mod get_document_builder; +mod get_partition_key_ranges_builder; mod get_permission_builer; mod get_user_builder; mod list_attachments_builder; @@ -55,6 +56,7 @@ pub use self::get_attachment_builder::GetAttachmentBuilder; pub use self::get_collection_builder::GetCollectionBuilder; pub use self::get_database_builder::GetDatabaseBuilder; pub use self::get_document_builder::GetDocumentBuilder; +pub use self::get_partition_key_ranges_builder::GetPartitionKeyRangesBuilder; pub use self::get_permission_builer::GetPermissionBuilder; pub use self::get_user_builder::GetUserBuilder; pub use self::list_attachments_builder::ListAttachmentsBuilder; diff --git a/azure_sdk_cosmos/src/responses/get_partition_key_ranges_response.rs b/azure_sdk_cosmos/src/responses/get_partition_key_ranges_response.rs new file mode 100644 index 000000000..cb2aee1b4 --- /dev/null +++ b/azure_sdk_cosmos/src/responses/get_partition_key_ranges_response.rs @@ -0,0 +1,75 @@ +use crate::from_headers::*; +use crate::PartitionKeyRange; +use azure_sdk_core::errors::AzureError; +use azure_sdk_core::session_token_from_headers; +use chrono::{DateTime, Utc}; +use http::HeaderMap; + +#[derive(Debug, Clone, PartialEq)] +pub struct GetPartitionKeyRangesResponse { + pub rid: String, + pub content_location: String, + pub server: String, + pub last_state_change: DateTime, + pub lsn: u64, + pub item_count: u32, + pub schema_version: String, + pub alt_content_path: String, + pub content_path: String, + pub role: u32, + pub global_committed_lsn: u64, + pub number_of_read_regions: u32, + pub transport_request_id: u64, + pub cosmos_llsn: u64, + pub session_token: String, + pub service_version: String, + pub activity_id: uuid::Uuid, + pub gateway_version: String, + pub date: DateTime, + pub partition_key_ranges: Vec, +} + +impl std::convert::TryFrom<(&HeaderMap, &[u8])> for GetPartitionKeyRangesResponse { + type Error = AzureError; + fn try_from(value: (&HeaderMap, &[u8])) -> Result { + let headers = value.0; + let body = value.1; + + debug!("body == {}", std::str::from_utf8(body)?); + + debug!("headers == {:#?}", headers); + + #[derive(Debug, Deserialize)] + struct Response { + #[serde(rename = "_rid")] + pub rid: String, + #[serde(rename = "PartitionKeyRanges")] + pub partition_key_ranges: Vec, + } + + let r: Response = serde_json::from_slice(body)?; + + Ok(Self { + rid: r.rid, + content_location: content_location_from_headers(headers)?.to_owned(), + server: server_from_headers(headers)?.to_owned(), + last_state_change: last_state_change_from_headers(headers)?, + lsn: lsn_from_headers(headers)?, + item_count: item_count_from_headers(headers)?, + schema_version: schema_version_from_headers(headers)?.to_owned(), + alt_content_path: alt_content_path_from_headers(headers)?.to_owned(), + content_path: content_path_from_headers(headers)?.to_owned(), + role: role_from_headers(headers)?, + global_committed_lsn: global_committed_lsn_from_headers(headers)?, + number_of_read_regions: number_of_read_regions_from_headers(headers)?, + transport_request_id: transport_request_id_from_headers(headers)?, + cosmos_llsn: cosmos_llsn_from_headers(headers)?, + service_version: service_version_from_headers(headers)?.to_owned(), + activity_id: activity_id_from_headers(headers)?, + session_token: session_token_from_headers(headers)?, + gateway_version: gateway_version_from_headers(headers)?.to_owned(), + date: date_from_headers(headers)?, + partition_key_ranges: r.partition_key_ranges, + }) + } +} diff --git a/azure_sdk_cosmos/src/responses/mod.rs b/azure_sdk_cosmos/src/responses/mod.rs index 07985f2de..6a12f593d 100644 --- a/azure_sdk_cosmos/src/responses/mod.rs +++ b/azure_sdk_cosmos/src/responses/mod.rs @@ -18,6 +18,7 @@ mod get_attachment_response; mod get_collection_response; mod get_database_response; mod get_document_response; +mod get_partition_key_ranges_response; mod get_permission_response; mod list_attachments_response; mod list_collections_response; @@ -51,6 +52,7 @@ pub use self::get_attachment_response::GetAttachmentResponse; pub use self::get_collection_response::GetCollectionResponse; pub use self::get_database_response::GetDatabaseResponse; pub use self::get_document_response::GetDocumentResponse; +pub use self::get_partition_key_ranges_response::GetPartitionKeyRangesResponse; pub use self::get_permission_response::GetPermissionResponse; pub use self::list_attachments_response::ListAttachmentsResponse; pub use self::list_collections_response::ListCollectionsResponse; diff --git a/azure_sdk_cosmos/tests/cosmos_collection.rs b/azure_sdk_cosmos/tests/cosmos_collection.rs index 3ea4aeaa6..37fbeea8c 100644 --- a/azure_sdk_cosmos/tests/cosmos_collection.rs +++ b/azure_sdk_cosmos/tests/cosmos_collection.rs @@ -45,6 +45,13 @@ async fn create_and_delete_collection() { let collection_after_get = collection_client.get_collection().execute().await.unwrap(); assert!(collection.collection.rid == collection_after_get.collection.rid); + // check GetPartitionKeyRanges: https://docs.microsoft.com/en-us/rest/api/cosmos-db/get-partition-key-ranges + collection_client + .get_partition_key_ranges() + .execute() + .await + .unwrap(); + // delete the collection collection_client .delete_collection()