From 9a05a49006acaa02b5f3f6b204354901a9247181 Mon Sep 17 00:00:00 2001 From: Ryan Levick Date: Wed, 27 Jul 2022 10:03:32 +0200 Subject: [PATCH 01/14] Move ApplyOnEdgeDevice --- sdk/core/src/macros.rs | 87 +++++++------ sdk/iot_hub/Cargo.toml | 1 + sdk/iot_hub/src/service/mod.rs | 3 +- .../service/requests/apply_on_edge_device.rs | 64 +++++++++ .../requests/apply_on_edge_device_builder.rs | 123 ------------------ sdk/iot_hub/src/service/requests/mod.rs | 4 +- 6 files changed, 117 insertions(+), 165 deletions(-) create mode 100644 sdk/iot_hub/src/service/requests/apply_on_edge_device.rs delete mode 100644 sdk/iot_hub/src/service/requests/apply_on_edge_device_builder.rs diff --git a/sdk/core/src/macros.rs b/sdk/core/src/macros.rs index de37777e24..7c53424b07 100644 --- a/sdk/core/src/macros.rs +++ b/sdk/core/src/macros.rs @@ -28,7 +28,7 @@ macro_rules! setters { (@single $name:ident : $typ:ty => $transform:expr) => { #[allow(clippy::redundant_field_names)] #[allow(clippy::needless_update)] - // TODO: Declare using idiomatic with_$name when https://github.com/Azure/azure-sdk-for-rust/issues/292 is resolved. + #[allow(missing_docs)] pub fn $name>(self, $name: P) -> Self { let $name: $typ = $name.into(); Self { @@ -123,6 +123,7 @@ macro_rules! setters { macro_rules! operation { // Construct the builder. (@builder + $(#[$outer:meta])* // The name of the operation and any generic params along with their constraints $name:ident<$($generic:ident: $first_constraint:ident $(+ $constraint:ident)* ),* $(+ $lt:lifetime)?>, // The client @@ -139,6 +140,7 @@ macro_rules! operation { ) => { azure_core::__private::paste! { #[derive(Debug, Clone)] + $(#[$outer])* pub struct [<$name Builder>]<$($generic)*> { client: $client, $($required: $rtype,)* @@ -169,8 +171,45 @@ macro_rules! operation { } } }; + // `operation! { #[stream] ListUsers, client: UserClient, ?consistency_level: ConsistencyLevel }` + (#[stream] $(#[$outer:meta])* $name:ident, + client: $client:ty, + $($required:ident: $rtype:ty,)* + $(?$optional:ident: $otype:ty),*) => { + $crate::operation!{ + @builder + $(#[$outer])* + $name<>, + client: $client, + @required + $($required: $rtype,)* + @optional + $($optional: $otype,)* + @nosetter + } + }; + (#[stream] $(#[$outer:meta])* + $name:ident, + client: $client:ty, + $($required:ident: $rtype:ty,)* + $(?$optional:ident: $otype:ty,)* + $(#[skip]$nosetter:ident: $nstype:ty),* + ) => { + $crate::operation!{ + @builder + $(#[$outer])* + $name<>, + client: $client, + @required + $($required: $rtype,)* + @optional + $($optional: $otype,)* + @nosetter + $($nosetter: $nstype),* + } + }; // Construct a builder and the `Future` related code - ($name:ident<$($generic:ident: $first_constraint:ident $(+ $constraint:ident)* ),* $(+ $lt:lifetime)?>, + ($(#[$outer:meta])* $name:ident<$($generic:ident: $first_constraint:ident $(+ $constraint:ident)* ),* $(+ $lt:lifetime)?>, client: $client:ty, @required $($required:ident: $rtype:ty,)* @@ -180,7 +219,9 @@ macro_rules! operation { $($nosetter:ident: $nstype:ty),* ) => { $crate::operation! { - @builder $name<$($generic: $first_constraint $(+ $constraint)*),* $(+ $lt)*>, + @builder + $(#[$outer])* + $name<$($generic: $first_constraint $(+ $constraint)*),* $(+ $lt)*>, client: $client, @required $($required: $rtype,)* @@ -202,11 +243,12 @@ macro_rules! operation { } }; // `operation! { CreateUser, client: UserClient, ?consistency_level: ConsistencyLevel }` - ($name:ident, + ($(#[$outer:meta])* $name:ident, client: $client:ty, $($required:ident: $rtype:ty,)* $(?$optional:ident: $otype:ty),*) => { $crate::operation!{ + $(#[$outer])* $name<>, client: $client, @required @@ -216,47 +258,14 @@ macro_rules! operation { @nosetter } }; - // `operation! { #[stream] ListUsers, client: UserClient, ?consistency_level: ConsistencyLevel }` - (#[stream] $name:ident, - client: $client:ty, - $($required:ident: $rtype:ty,)* - $(?$optional:ident: $otype:ty),*) => { - $crate::operation!{ - @builder - $name<>, - client: $client, - @required - $($required: $rtype,)* - @optional - $($optional: $otype,)* - @nosetter - } - }; - (#[stream] $name:ident, - client: $client:ty, - $($required:ident: $rtype:ty,)* - $(?$optional:ident: $otype:ty,)* - $(#[skip]$nosetter:ident: $nstype:ty),* - ) => { - $crate::operation!{ - @builder - $name<>, - client: $client, - @required - $($required: $rtype,)* - @optional - $($optional: $otype,)* - @nosetter - $($nosetter: $nstype),* - } - }; // `operation! { CreateDocument, client: UserClient, ?consistency_level: ConsistencyLevel, ??other_field: bool }` - ($name:ident<$($generic:ident: $first_constraint:ident $(+ $constraint:ident)*),* $(+ $lt:lifetime)?>, + ($(#[$outer:meta])* $name:ident<$($generic:ident: $first_constraint:ident $(+ $constraint:ident)*),* $(+ $lt:lifetime)?>, client: $client:ty, $($required:ident: $rtype:ty,)* $(?$optional:ident: $otype:ty,)* $(#[skip] $nosetter:ident: $nstype:ty),*) => { $crate::operation!{ + $(#[$outer])* $name<$($generic: $first_constraint $(+ $constraint)*),* $(+ $lt)*>, client: $client, @required diff --git a/sdk/iot_hub/Cargo.toml b/sdk/iot_hub/Cargo.toml index 30bba9c206..3c8786dc7b 100644 --- a/sdk/iot_hub/Cargo.toml +++ b/sdk/iot_hub/Cargo.toml @@ -18,6 +18,7 @@ serde_derive = "1.0" sha2 = "0.10" url = "2.2" thiserror = "1.0" +futures = "0.3" [dev-dependencies] env_logger = "0.9" diff --git a/sdk/iot_hub/src/service/mod.rs b/sdk/iot_hub/src/service/mod.rs index e83097c442..bca4e6db13 100644 --- a/sdk/iot_hub/src/service/mod.rs +++ b/sdk/iot_hub/src/service/mod.rs @@ -35,6 +35,7 @@ pub const API_VERSION: &str = "2020-05-31-preview"; /// - providing the connection string. /// The IoTHubService then uses the provided information to create a SAS token that it will /// use to communicate with the IoT Hub. +#[derive(Clone, Debug)] pub struct ServiceClient { http_client: Arc, /// The name of the IoT Hub. @@ -670,7 +671,7 @@ impl ServiceClient { where S: Into, { - ApplyOnEdgeDeviceBuilder::new(self, device_id.into()) + ApplyOnEdgeDeviceBuilder::new(self.clone(), device_id.into()) } /// Get a configuration diff --git a/sdk/iot_hub/src/service/requests/apply_on_edge_device.rs b/sdk/iot_hub/src/service/requests/apply_on_edge_device.rs new file mode 100644 index 0000000000..6f38d61bb2 --- /dev/null +++ b/sdk/iot_hub/src/service/requests/apply_on_edge_device.rs @@ -0,0 +1,64 @@ +use crate::service::{ServiceClient, API_VERSION}; + +use azure_core::{operation, Method}; +use serde::Serialize; +operation! { + /// The ApplyOnEdgeDeviceBuilder is used to construct a new device identity + /// or the update an existing one. + ApplyOnEdgeDevice, + client: ServiceClient, + device_id: String, + ?device_content: serde_json::Value, + ?module_content: serde_json::Value, + ?modules_content: serde_json::Value +} + +impl ApplyOnEdgeDeviceBuilder { + /// Performs the apply on edge device request + /// + /// + /// ``` + /// use azure_iot_hub::service::ServiceClient; + /// use serde_json; + /// + /// # let connection_string = "HostName=cool-iot-hub.azure-devices.net;SharedAccessKeyName=iot_hubowner;SharedAccessKey=YSB2ZXJ5IHNlY3VyZSBrZXkgaXMgaW1wb3J0YW50Cg=="; + /// # let http_client = azure_core::new_http_client(); + /// + /// let iot_hub = ServiceClient::from_connection_string(http_client, connection_string, 3600).expect("Failed to create the ServiceClient!"); + /// iot_hub.apply_on_edge_device("some-device").execute(); + /// ``` + pub fn into_future(self) -> ApplyOnEdgeDevice { + Box::pin(async move { + let uri = format!( + "https://{}.azure-devices.net/devices/{}/applyConfigurationContent?api-version={}", + self.client.iot_hub_name, self.device_id, API_VERSION + ); + + let mut request = self.client.finalize_request(&uri, Method::Post)?; + let body = ApplyOnEdgeDeviceBody { + device_content: self.device_content.unwrap_or_default(), + module_content: self.module_content.unwrap_or_default(), + modules_content: self.modules_content.unwrap_or_default(), + }; + + let body = azure_core::to_json(&body)?; + request.set_body(body); + + self.client + .http_client() + .execute_request_check_status(&request) + .await?; + Ok(()) + }) + } +} + +pub type ApplyOnEdgeDeviceResponse = (); + +#[derive(Serialize)] +#[serde(rename_all = "camelCase")] +struct ApplyOnEdgeDeviceBody { + device_content: serde_json::Value, + module_content: serde_json::Value, + modules_content: serde_json::Value, +} diff --git a/sdk/iot_hub/src/service/requests/apply_on_edge_device_builder.rs b/sdk/iot_hub/src/service/requests/apply_on_edge_device_builder.rs deleted file mode 100644 index 1f856ab2f5..0000000000 --- a/sdk/iot_hub/src/service/requests/apply_on_edge_device_builder.rs +++ /dev/null @@ -1,123 +0,0 @@ -use crate::service::{ServiceClient, API_VERSION}; - -use azure_core::Method; -use serde::Serialize; -/// The ApplyOnEdgeDeviceBuilder is used to construct a new device identity -/// or the update an existing one. -pub struct ApplyOnEdgeDeviceBuilder<'a> { - service_client: &'a ServiceClient, - device_id: String, - device_content: serde_json::Value, - module_content: serde_json::Value, - modules_content: serde_json::Value, -} - -impl<'a> ApplyOnEdgeDeviceBuilder<'a> { - pub(crate) fn new(service_client: &'a ServiceClient, device_id: String) -> Self { - Self { - service_client, - device_id, - device_content: serde_json::json!({}), - module_content: serde_json::json!({}), - modules_content: serde_json::json!({}), - } - } - - /// Sets the device content - /// - /// - /// ``` - /// use azure_iot_hub::service::ServiceClient; - /// use serde_json; - /// - /// # let connection_string = "HostName=cool-iot-hub.azure-devices.net;SharedAccessKeyName=iot_hubowner;SharedAccessKey=YSB2ZXJ5IHNlY3VyZSBrZXkgaXMgaW1wb3J0YW50Cg=="; - /// # let http_client = azure_core::new_http_client(); - /// - /// let iot_hub = ServiceClient::from_connection_string(http_client, connection_string, 3600).expect("Failed to create the ServiceClient!"); - /// let edge_configuration_builder = iot_hub.apply_on_edge_device("some-device").device_content(serde_json::json!({})); - /// ``` - pub fn device_content(mut self, device_content: serde_json::Value) -> Self { - self.device_content = device_content; - self - } - - /// Sets the module content - /// - /// - /// ``` - /// use azure_iot_hub::service::ServiceClient; - /// use serde_json; - /// - /// # let connection_string = "HostName=cool-iot-hub.azure-devices.net;SharedAccessKeyName=iot_hubowner;SharedAccessKey=YSB2ZXJ5IHNlY3VyZSBrZXkgaXMgaW1wb3J0YW50Cg=="; - /// # let http_client = azure_core::new_http_client(); - /// - /// let iot_hub = ServiceClient::from_connection_string(http_client, connection_string, 3600).expect("Failed to create the ServiceClient!"); - /// let edge_configuration_builder = iot_hub.apply_on_edge_device("some-device").module_content(serde_json::json!({})); - /// ``` - pub fn module_content(mut self, module_content: serde_json::Value) -> Self { - self.module_content = module_content; - self - } - - /// Sets the modules content - /// - /// - /// ``` - /// use azure_iot_hub::service::ServiceClient; - /// use serde_json; - /// - /// # let connection_string = "HostName=cool-iot-hub.azure-devices.net;SharedAccessKeyName=iot_hubowner;SharedAccessKey=YSB2ZXJ5IHNlY3VyZSBrZXkgaXMgaW1wb3J0YW50Cg=="; - /// # let http_client = azure_core::new_http_client(); - /// - /// let iot_hub = ServiceClient::from_connection_string(http_client, connection_string, 3600).expect("Failed to create the ServiceClient!"); - /// let edge_configuration_builder = iot_hub.apply_on_edge_device("some-device").modules_content(serde_json::json!({})); - /// ``` - pub fn modules_content(mut self, modules_content: serde_json::Value) -> Self { - self.modules_content = modules_content; - self - } - - /// Performs the apply on edge device request - /// - /// - /// ``` - /// use azure_iot_hub::service::ServiceClient; - /// use serde_json; - /// - /// # let connection_string = "HostName=cool-iot-hub.azure-devices.net;SharedAccessKeyName=iot_hubowner;SharedAccessKey=YSB2ZXJ5IHNlY3VyZSBrZXkgaXMgaW1wb3J0YW50Cg=="; - /// # let http_client = azure_core::new_http_client(); - /// - /// let iot_hub = ServiceClient::from_connection_string(http_client, connection_string, 3600).expect("Failed to create the ServiceClient!"); - /// iot_hub.apply_on_edge_device("some-device").execute(); - /// ``` - pub async fn execute(self) -> azure_core::Result<()> { - let uri = format!( - "https://{}.azure-devices.net/devices/{}/applyConfigurationContent?api-version={}", - self.service_client.iot_hub_name, self.device_id, API_VERSION - ); - - let mut request = self.service_client.finalize_request(&uri, Method::Post)?; - let body = ApplyOnEdgeDeviceBody { - device_content: self.device_content, - module_content: self.module_content, - modules_content: self.modules_content, - }; - - let body = azure_core::to_json(&body)?; - request.set_body(body); - - self.service_client - .http_client() - .execute_request_check_status(&request) - .await?; - Ok(()) - } -} - -#[derive(Serialize)] -#[serde(rename_all = "camelCase")] -struct ApplyOnEdgeDeviceBody { - device_content: serde_json::Value, - module_content: serde_json::Value, - modules_content: serde_json::Value, -} diff --git a/sdk/iot_hub/src/service/requests/mod.rs b/sdk/iot_hub/src/service/requests/mod.rs index a2c5c2f8b9..911631d285 100644 --- a/sdk/iot_hub/src/service/requests/mod.rs +++ b/sdk/iot_hub/src/service/requests/mod.rs @@ -1,4 +1,4 @@ -mod apply_on_edge_device_builder; +mod apply_on_edge_device; mod create_or_update_configuration_builder; mod create_or_update_device_identity_builder; mod create_or_update_module_identity_builder; @@ -11,7 +11,7 @@ mod invoke_method_builder; mod query_builder; mod update_or_replace_twin_builder; -pub use apply_on_edge_device_builder::ApplyOnEdgeDeviceBuilder; +pub use apply_on_edge_device::ApplyOnEdgeDeviceBuilder; pub use create_or_update_configuration_builder::CreateOrUpdateConfigurationBuilder; pub use create_or_update_device_identity_builder::CreateOrUpdateDeviceIdentityBuilder; pub use create_or_update_module_identity_builder::CreateOrUpdateModuleIdentityBuilder; From f65ae6353e77dab3912bd9fd89262233d6cea76b Mon Sep 17 00:00:00 2001 From: Ryan Levick Date: Wed, 27 Jul 2022 10:11:43 +0200 Subject: [PATCH 02/14] Move CreateOrUpdateConfiguration --- sdk/iot_hub/src/service/mod.rs | 4 +- .../create_or_update_configuration.rs | 81 ++++++++++ .../create_or_update_configuration_builder.rs | 152 ------------------ sdk/iot_hub/src/service/requests/mod.rs | 4 +- .../src/service/resources/configuration.rs | 2 +- 5 files changed, 86 insertions(+), 157 deletions(-) create mode 100644 sdk/iot_hub/src/service/requests/create_or_update_configuration.rs delete mode 100644 sdk/iot_hub/src/service/requests/create_or_update_configuration_builder.rs diff --git a/sdk/iot_hub/src/service/mod.rs b/sdk/iot_hub/src/service/mod.rs index bca4e6db13..b96b756dae 100644 --- a/sdk/iot_hub/src/service/mod.rs +++ b/sdk/iot_hub/src/service/mod.rs @@ -734,7 +734,7 @@ impl ServiceClient { T: Into, { CreateOrUpdateConfigurationBuilder::new( - self, + self.clone(), configuration_id.into(), priority, target_condition.into(), @@ -768,7 +768,7 @@ impl ServiceClient { U: Into, { CreateOrUpdateConfigurationBuilder::new( - self, + self.clone(), configuration_id.into(), priority, target_condition.into(), diff --git a/sdk/iot_hub/src/service/requests/create_or_update_configuration.rs b/sdk/iot_hub/src/service/requests/create_or_update_configuration.rs new file mode 100644 index 0000000000..c3c46ffaac --- /dev/null +++ b/sdk/iot_hub/src/service/requests/create_or_update_configuration.rs @@ -0,0 +1,81 @@ +use azure_core::headers; +use azure_core::Method; +use serde::Serialize; +use std::collections::HashMap; +use std::convert::TryInto; + +use crate::service::resources::{ConfigurationContent, ConfigurationMetrics}; +use crate::service::responses::ConfigurationResponse; +use crate::service::{ServiceClient, API_VERSION}; + +azure_core::operation! { + /// The CreateOrUpdateConfigurationBuilder is used to construct a new configuration + /// or update an existing one. + CreateOrUpdateConfiguration, + client: ServiceClient, + configuration_id: String, + priority: u64, + target_condition: String, + etag: Option, + ?content: ConfigurationContent, + ?metrics: HashMap, + ?labels: HashMap +} + +impl CreateOrUpdateConfigurationBuilder { + /// Performs the create or update request on the device identity + pub async fn into_future(self) -> CreateOrUpdateConfiguration { + Box::pin(async move { + let uri = format!( + "https://{}.azure-devices.net/configurations/{}?api-version={}", + self.client.iot_hub_name, &self.configuration_id, API_VERSION + ); + + let mut request = self.client.finalize_request(&uri, Method::Put)?; + + match &self.etag { + Some(etag) => { + request.insert_header(headers::IF_MATCH, format!("\"{}\"", etag)); + } + None => (), + } + + let body = CreateOrUpdateConfigurationBody { + content: self.content.unwrap_or_default(), + etag: self.etag, + id: &self.configuration_id, + labels: self.labels.unwrap_or_default(), + metrics: ConfigurationMetrics { + queries: self.metrics.unwrap_or_default(), + results: HashMap::new(), + }, + priority: self.priority, + target_condition: &self.target_condition, + }; + + let body = azure_core::to_json(&body)?; + request.set_body(body); + + self.client + .http_client() + .execute_request_check_status(&request) + .await? + .try_into() + }) + } +} + +pub type CreateOrUpdateConfigurationResponse = ConfigurationResponse; + +#[derive(Serialize)] +#[serde(rename_all = "camelCase")] +struct CreateOrUpdateConfigurationBody<'a, 'b> { + content: ConfigurationContent, + #[serde(skip_serializing_if = "Option::is_none")] + etag: Option, + id: &'a str, + labels: HashMap, + metrics: ConfigurationMetrics, + priority: u64, + target_condition: &'b str, +} diff --git a/sdk/iot_hub/src/service/requests/create_or_update_configuration_builder.rs b/sdk/iot_hub/src/service/requests/create_or_update_configuration_builder.rs deleted file mode 100644 index 837ee6d177..0000000000 --- a/sdk/iot_hub/src/service/requests/create_or_update_configuration_builder.rs +++ /dev/null @@ -1,152 +0,0 @@ -use azure_core::headers; -use azure_core::Method; -use serde::Serialize; -use std::collections::HashMap; -use std::convert::TryInto; - -use crate::service::resources::{ConfigurationContent, ConfigurationMetrics}; -use crate::service::responses::ConfigurationResponse; -use crate::service::{ServiceClient, API_VERSION}; - -/// The CreateOrUpdateConfigurationBuilder is used to construct a new configuration -/// or update an existing one. -pub struct CreateOrUpdateConfigurationBuilder<'a> { - service_client: &'a ServiceClient, - configuration_id: String, - priority: u64, - target_condition: String, - etag: Option, - content: ConfigurationContent, - metrics: HashMap, - labels: HashMap, -} - -impl<'a> CreateOrUpdateConfigurationBuilder<'a> { - pub(crate) fn new( - service_client: &'a ServiceClient, - configuration_id: String, - priority: u64, - target_condition: String, - etag: Option, - ) -> Self { - Self { - service_client, - configuration_id, - priority, - target_condition, - etag, - content: ConfigurationContent { - device_content: None, - module_content: None, - modules_content: None, - }, - metrics: HashMap::new(), - labels: HashMap::new(), - } - } - - /// Sets the device content for the configuration - /// The content cannot be updated once it has been created. - pub fn device_content(mut self, device_content: serde_json::Value) -> Self { - self.content.device_content = Some(device_content); - self - } - - /// Sets the module content for the configuration. - /// The content cannot be updated once it has been created. - pub fn module_content(mut self, module_content: serde_json::Value) -> Self { - self.content.module_content = Some(module_content); - self - } - - /// Sets the module content for the configuration - /// The content cannot be updated once it has been created. - pub fn modules_content(mut self, modules_content: serde_json::Value) -> Self { - self.content.modules_content = Some(modules_content); - self - } - - /// Add a metric to the configuration - pub fn metric(mut self, key: S, value: T) -> Self - where - S: Into, - T: Into, - { - self.metrics.insert(key.into(), value.into()); - self - } - - /// Add multiple metrics to the configuration. - pub fn metrics(mut self, metrics: HashMap) -> Self { - self.metrics = metrics; - self - } - - /// Add a label to the configuration. - pub fn label(mut self, key: S, value: T) -> Self - where - S: Into, - T: Into, - { - self.labels.insert(key.into(), value.into()); - self - } - - /// Add multiple labels to the configuration. - pub fn labels(mut self, labels: HashMap) -> Self { - self.labels = labels; - self - } - - /// Performs the create or update request on the device identity - pub async fn execute(self) -> azure_core::Result { - let uri = format!( - "https://{}.azure-devices.net/configurations/{}?api-version={}", - self.service_client.iot_hub_name, &self.configuration_id, API_VERSION - ); - - let mut request = self.service_client.finalize_request(&uri, Method::Put)?; - - match &self.etag { - Some(etag) => { - request.insert_header(headers::IF_MATCH, format!("\"{}\"", etag)); - } - None => (), - } - - let body = CreateOrUpdateConfigurationBody { - content: self.content, - etag: self.etag, - id: &self.configuration_id, - labels: self.labels, - metrics: ConfigurationMetrics { - queries: self.metrics, - results: HashMap::new(), - }, - priority: self.priority, - target_condition: &self.target_condition, - }; - - let body = azure_core::to_json(&body)?; - request.set_body(body); - - self.service_client - .http_client() - .execute_request_check_status(&request) - .await? - .try_into() - } -} - -#[derive(Serialize)] -#[serde(rename_all = "camelCase")] -struct CreateOrUpdateConfigurationBody<'a, 'b> { - content: ConfigurationContent, - #[serde(skip_serializing_if = "Option::is_none")] - etag: Option, - id: &'a str, - labels: HashMap, - metrics: ConfigurationMetrics, - priority: u64, - target_condition: &'b str, -} diff --git a/sdk/iot_hub/src/service/requests/mod.rs b/sdk/iot_hub/src/service/requests/mod.rs index 911631d285..f7e3e38e20 100644 --- a/sdk/iot_hub/src/service/requests/mod.rs +++ b/sdk/iot_hub/src/service/requests/mod.rs @@ -1,5 +1,5 @@ mod apply_on_edge_device; -mod create_or_update_configuration_builder; +mod create_or_update_configuration; mod create_or_update_device_identity_builder; mod create_or_update_module_identity_builder; mod delete_configuration_builder; @@ -12,7 +12,7 @@ mod query_builder; mod update_or_replace_twin_builder; pub use apply_on_edge_device::ApplyOnEdgeDeviceBuilder; -pub use create_or_update_configuration_builder::CreateOrUpdateConfigurationBuilder; +pub use create_or_update_configuration::CreateOrUpdateConfigurationBuilder; pub use create_or_update_device_identity_builder::CreateOrUpdateDeviceIdentityBuilder; pub use create_or_update_module_identity_builder::CreateOrUpdateModuleIdentityBuilder; pub use delete_configuration_builder::DeleteConfigurationBuilder; diff --git a/sdk/iot_hub/src/service/resources/configuration.rs b/sdk/iot_hub/src/service/resources/configuration.rs index 0116052202..4468a1298a 100644 --- a/sdk/iot_hub/src/service/resources/configuration.rs +++ b/sdk/iot_hub/src/service/resources/configuration.rs @@ -2,7 +2,7 @@ use serde::{Deserialize, Serialize}; use std::collections::HashMap; /// The configuration content for devices or modules on edge devices. -#[derive(Serialize, Deserialize, Debug, PartialEq, Clone)] +#[derive(Serialize, Deserialize, Debug, PartialEq, Clone, Default)] #[serde(rename_all = "camelCase")] pub struct ConfigurationContent { /// The device configuration content. From 619fc60541cea46b76d0e705c541e17e0c63cb7b Mon Sep 17 00:00:00 2001 From: Ryan Levick Date: Wed, 27 Jul 2022 10:26:58 +0200 Subject: [PATCH 03/14] CreateOrUpdateDeviceIdentity --- sdk/iot_hub/src/service/mod.rs | 41 ++++++- .../create_or_update_device_identity.rs | 90 ++++++++++++++++ ...reate_or_update_device_identity_builder.rs | 100 ------------------ sdk/iot_hub/src/service/requests/mod.rs | 4 +- sdk/iot_hub/src/service/resources/identity.rs | 14 +-- 5 files changed, 135 insertions(+), 114 deletions(-) create mode 100644 sdk/iot_hub/src/service/requests/create_or_update_device_identity.rs delete mode 100644 sdk/iot_hub/src/service/requests/create_or_update_device_identity_builder.rs diff --git a/sdk/iot_hub/src/service/mod.rs b/sdk/iot_hub/src/service/mod.rs index b96b756dae..a0dbce9a48 100644 --- a/sdk/iot_hub/src/service/mod.rs +++ b/sdk/iot_hub/src/service/mod.rs @@ -25,6 +25,8 @@ use crate::service::responses::{ ModuleTwinResponse, MultipleConfigurationResponse, }; +use self::resources::{AuthenticationMechanism, Status}; + /// The API version to use for any requests pub const API_VERSION: &str = "2020-05-31-preview"; @@ -498,8 +500,23 @@ impl ServiceClient { /// let device = iot_hub.create_device_identity() /// .execute("some-existing-device", Status::Enabled, AuthenticationMechanism::new_using_symmetric_key("first-key", "second-key")); /// ``` - pub fn create_device_identity(&self) -> CreateOrUpdateDeviceIdentityBuilder { - CreateOrUpdateDeviceIdentityBuilder::new(self, IdentityOperation::Create, None) + pub fn create_device_identity( + &self, + device_id: S, + status: Status, + authentication: AuthenticationMechanism, + ) -> CreateOrUpdateDeviceIdentityBuilder + where + S: Into, + { + CreateOrUpdateDeviceIdentityBuilder::new( + self.clone(), + IdentityOperation::Create, + device_id.into(), + status, + authentication, + None, + ) } /// Update an existing device identity @@ -515,11 +532,25 @@ impl ServiceClient { /// let device = iot_hub.update_device_identity("etag-of-device-to-update") /// .execute("some-existing-device", Status::Enabled, AuthenticationMechanism::new_using_symmetric_key("first-key", "second-key")); /// ``` - pub fn update_device_identity(&self, etag: S) -> CreateOrUpdateDeviceIdentityBuilder + pub fn update_device_identity( + &self, + device_id: S1, + status: Status, + authentication: AuthenticationMechanism, + etag: S2, + ) -> CreateOrUpdateDeviceIdentityBuilder where - S: Into, + S1: Into, + S2: Into, { - CreateOrUpdateDeviceIdentityBuilder::new(self, IdentityOperation::Update, Some(etag.into())) + CreateOrUpdateDeviceIdentityBuilder::new( + self.clone(), + IdentityOperation::Update, + device_id.into(), + status, + authentication, + Some(etag.into()), + ) } /// Delete a device identity diff --git a/sdk/iot_hub/src/service/requests/create_or_update_device_identity.rs b/sdk/iot_hub/src/service/requests/create_or_update_device_identity.rs new file mode 100644 index 0000000000..e295b03f3c --- /dev/null +++ b/sdk/iot_hub/src/service/requests/create_or_update_device_identity.rs @@ -0,0 +1,90 @@ +use crate::service::resources::{ + identity::DesiredCapability, identity::IdentityOperation, AuthenticationMechanism, + DeviceCapabilities, Status, +}; +use crate::service::responses::DeviceIdentityResponse; +use crate::service::{ServiceClient, API_VERSION}; +use azure_core::error::{Error, ErrorKind}; +use azure_core::headers; +use azure_core::Method; +use serde::Serialize; +use std::convert::TryInto; + +azure_core::operation! { + /// The CreateOrUpdateDeviceIdentityBuilder is used to construct a new device identity + /// or the update an existing one. + CreateOrUpdateDeviceIdentity, + client: ServiceClient, + operation: IdentityOperation, + device_id: String, + status: Status, + authentication: AuthenticationMechanism, + etag: Option, + ?capabilities: DeviceCapabilities +} + +impl CreateOrUpdateDeviceIdentityBuilder { + /// Sets a device capability on the device + pub fn device_capability(mut self, desired_capability: DesiredCapability) -> Self { + match desired_capability { + DesiredCapability::IotEdge => { + let caps = self + .capabilities + .get_or_insert(DeviceCapabilities::default()); + caps.iotedge = true; + } + } + self + } + + /// Performs the create or update request on the device identity + pub fn into_future(self) -> CreateOrUpdateDeviceIdentity { + Box::pin(async move { + let uri = format!( + "https://{}.azure-devices.net/devices/{}?api-version={}", + self.client.iot_hub_name, self.device_id, API_VERSION + ); + + let mut request = self.client.finalize_request(&uri, Method::Put)?; + + if self.operation == IdentityOperation::Update { + match &self.etag { + Some(etag) => { + request.insert_header(headers::IF_MATCH, format!("\"{}\"", etag)); + } + None => return Err(Error::message(ErrorKind::Other, "etag is not set")), + } + } + + let body = CreateOrUpdateDeviceIdentityBody { + authentication: self.authentication, + device_id: &self.device_id, + status: self.status, + capabilities: self.capabilities.unwrap_or_default(), + etag: self.etag, + }; + + let body = azure_core::to_json(&body)?; + request.set_body(body); + + self.client + .http_client() + .execute_request_check_status(&request) + .await? + .try_into() + }) + } +} + +pub type CreateOrUpdateDeviceIdentityResponse = DeviceIdentityResponse; + +#[derive(Serialize)] +#[serde(rename_all = "camelCase")] +struct CreateOrUpdateDeviceIdentityBody<'a> { + authentication: AuthenticationMechanism, + device_id: &'a str, + status: Status, + capabilities: DeviceCapabilities, + #[serde(skip_serializing_if = "Option::is_none")] + etag: Option, +} diff --git a/sdk/iot_hub/src/service/requests/create_or_update_device_identity_builder.rs b/sdk/iot_hub/src/service/requests/create_or_update_device_identity_builder.rs deleted file mode 100644 index d3decacbf9..0000000000 --- a/sdk/iot_hub/src/service/requests/create_or_update_device_identity_builder.rs +++ /dev/null @@ -1,100 +0,0 @@ -use crate::service::resources::{ - identity::DesiredCapability, identity::IdentityOperation, AuthenticationMechanism, - DeviceCapabilities, Status, -}; -use crate::service::responses::DeviceIdentityResponse; -use crate::service::{ServiceClient, API_VERSION}; -use azure_core::error::{Error, ErrorKind}; -use azure_core::headers; -use azure_core::Method; -use serde::Serialize; -use std::convert::TryInto; - -/// The CreateOrUpdateDeviceIdentityBuilder is used to construct a new device identity -/// or the update an existing one. -pub struct CreateOrUpdateDeviceIdentityBuilder<'a> { - service_client: &'a ServiceClient, - capabilities: DeviceCapabilities, - etag: Option, - operation: IdentityOperation, -} - -impl<'a> CreateOrUpdateDeviceIdentityBuilder<'a> { - pub(crate) fn new( - service_client: &'a ServiceClient, - operation: IdentityOperation, - etag: Option, - ) -> Self { - Self { - service_client, - capabilities: DeviceCapabilities::default(), - etag, - operation, - } - } - - /// Sets a device capability on the device - pub fn device_capability(mut self, desired_capability: DesiredCapability) -> Self { - match desired_capability { - DesiredCapability::IotEdge => self.capabilities.iotedge = true, - } - self - } - - /// Performs the create or update request on the device identity - pub async fn execute( - self, - device_id: S, - status: Status, - authentication: AuthenticationMechanism, - ) -> azure_core::Result - where - S: AsRef, - { - let uri = format!( - "https://{}.azure-devices.net/devices/{}?api-version={}", - self.service_client.iot_hub_name, - device_id.as_ref(), - API_VERSION - ); - - let mut request = self.service_client.finalize_request(&uri, Method::Put)?; - - if self.operation == IdentityOperation::Update { - match &self.etag { - Some(etag) => { - request.insert_header(headers::IF_MATCH, format!("\"{}\"", etag)); - } - None => return Err(Error::message(ErrorKind::Other, "etag is not set")), - } - } - - let body = CreateOrUpdateDeviceIdentityBody { - authentication, - device_id: device_id.as_ref(), - status, - capabilities: self.capabilities, - etag: self.etag, - }; - - let body = azure_core::to_json(&body)?; - request.set_body(body); - - self.service_client - .http_client() - .execute_request_check_status(&request) - .await? - .try_into() - } -} - -#[derive(Serialize)] -#[serde(rename_all = "camelCase")] -struct CreateOrUpdateDeviceIdentityBody<'a> { - authentication: AuthenticationMechanism, - device_id: &'a str, - status: Status, - capabilities: DeviceCapabilities, - #[serde(skip_serializing_if = "Option::is_none")] - etag: Option, -} diff --git a/sdk/iot_hub/src/service/requests/mod.rs b/sdk/iot_hub/src/service/requests/mod.rs index f7e3e38e20..d5ac83108f 100644 --- a/sdk/iot_hub/src/service/requests/mod.rs +++ b/sdk/iot_hub/src/service/requests/mod.rs @@ -1,6 +1,6 @@ mod apply_on_edge_device; mod create_or_update_configuration; -mod create_or_update_device_identity_builder; +mod create_or_update_device_identity; mod create_or_update_module_identity_builder; mod delete_configuration_builder; mod delete_identity_builder; @@ -13,7 +13,7 @@ mod update_or_replace_twin_builder; pub use apply_on_edge_device::ApplyOnEdgeDeviceBuilder; pub use create_or_update_configuration::CreateOrUpdateConfigurationBuilder; -pub use create_or_update_device_identity_builder::CreateOrUpdateDeviceIdentityBuilder; +pub use create_or_update_device_identity::CreateOrUpdateDeviceIdentityBuilder; pub use create_or_update_module_identity_builder::CreateOrUpdateModuleIdentityBuilder; pub use delete_configuration_builder::DeleteConfigurationBuilder; pub use delete_identity_builder::DeleteIdentityBuilder; diff --git a/sdk/iot_hub/src/service/resources/identity.rs b/sdk/iot_hub/src/service/resources/identity.rs index e01ae61c2d..3e4dee0f9e 100644 --- a/sdk/iot_hub/src/service/resources/identity.rs +++ b/sdk/iot_hub/src/service/resources/identity.rs @@ -16,7 +16,7 @@ pub enum ConnectionState { } /// Device or module status -#[derive(Serialize, Deserialize, Debug, PartialEq)] +#[derive(Serialize, Deserialize, Debug, Clone, PartialEq)] #[serde(rename_all = "lowercase")] pub enum Status { /// The device or module is disabled @@ -26,7 +26,7 @@ pub enum Status { } /// Representation of device capabilities. -#[derive(Default, Serialize, Deserialize, Debug, PartialEq)] +#[derive(Default, Serialize, Deserialize, Clone, Debug, PartialEq)] pub struct DeviceCapabilities { #[serde(rename = "iotEdge")] /// Whether the device has the IoT Edge capability or not. @@ -34,7 +34,7 @@ pub struct DeviceCapabilities { } /// Representation of a symmetric key for authentication. -#[derive(Serialize, Deserialize, Debug, PartialEq, Default)] +#[derive(Serialize, Deserialize, Debug, PartialEq, Clone, Default)] pub struct SymmetricKey { /// The primary key. pub primary_key: Option, @@ -43,7 +43,7 @@ pub struct SymmetricKey { } /// Representation of a x509 thumbprint for authentication. -#[derive(Default, Serialize, Deserialize, Debug, PartialEq)] +#[derive(Default, Serialize, Deserialize, Debug, Clone, PartialEq)] #[serde(rename_all = "camelCase")] pub struct X509ThumbPrint { /// The primary thumbprint. @@ -53,7 +53,7 @@ pub struct X509ThumbPrint { } /// AuthenticationType of a module or device. -#[derive(Serialize, Debug, Deserialize, PartialEq)] +#[derive(Serialize, Debug, Deserialize, Clone, PartialEq)] pub enum AuthenticationType { /// Authentication using a certificate authority. #[serde(rename = "certificateAuthority")] @@ -70,7 +70,7 @@ pub enum AuthenticationType { } /// The authentication mechanism for a device or module identity. -#[derive(Serialize, Deserialize, Debug, PartialEq)] +#[derive(Serialize, Deserialize, Debug, Clone, PartialEq)] #[serde(rename_all = "camelCase")] pub struct AuthenticationMechanism { /// The symmetric key pair used for authentication. @@ -126,7 +126,7 @@ impl AuthenticationMechanism { } /// The operation to perform on an identity -#[derive(PartialEq)] +#[derive(Debug, Clone, PartialEq)] pub(crate) enum IdentityOperation { Create, Update, From 390a6ce5e72f17544340315aa738e247874b74af Mon Sep 17 00:00:00 2001 From: Ryan Levick Date: Wed, 27 Jul 2022 10:37:22 +0200 Subject: [PATCH 04/14] CreateOrUpdateModuleIdentity --- sdk/iot_hub/src/service/mod.rs | 47 +++++++++- .../create_or_update_module_identity.rs | 74 +++++++++++++++ ...reate_or_update_module_identity_builder.rs | 91 ------------------- sdk/iot_hub/src/service/requests/mod.rs | 4 +- 4 files changed, 118 insertions(+), 98 deletions(-) create mode 100644 sdk/iot_hub/src/service/requests/create_or_update_module_identity.rs delete mode 100644 sdk/iot_hub/src/service/requests/create_or_update_module_identity_builder.rs diff --git a/sdk/iot_hub/src/service/mod.rs b/sdk/iot_hub/src/service/mod.rs index a0dbce9a48..1a7d9132ca 100644 --- a/sdk/iot_hub/src/service/mod.rs +++ b/sdk/iot_hub/src/service/mod.rs @@ -615,8 +615,27 @@ impl ServiceClient { /// let device = iot_hub.create_module_identity() /// .execute("some-existing-device", "some-existing-module", "IoTEdge", AuthenticationMechanism::new_using_symmetric_key("first-key", "second-key")); /// ``` - pub fn create_module_identity(&self) -> CreateOrUpdateModuleIdentityBuilder { - CreateOrUpdateModuleIdentityBuilder::new(self, IdentityOperation::Create, None) + pub fn create_module_identity( + &self, + device_id: S1, + module_id: S2, + managed_by: S3, + authentication: AuthenticationMechanism, + ) -> CreateOrUpdateModuleIdentityBuilder + where + S1: Into, + S2: Into, + S3: Into, + { + CreateOrUpdateModuleIdentityBuilder::new( + self.clone(), + IdentityOperation::Create, + device_id.into(), + module_id.into(), + managed_by.into(), + authentication, + None, + ) } /// Update an existing module identity @@ -632,11 +651,29 @@ impl ServiceClient { /// let device = iot_hub.update_module_identity("etag-of-device-to-update") /// .execute("some-existing-device", "some-existing-module", "IoTEdge", AuthenticationMechanism::new_using_symmetric_key("first-key", "second-key")); /// ``` - pub fn update_module_identity(&self, etag: S) -> CreateOrUpdateModuleIdentityBuilder + pub fn update_module_identity( + &self, + device_id: S1, + module_id: S2, + managed_by: S3, + etag: S4, + authentication: AuthenticationMechanism, + ) -> CreateOrUpdateModuleIdentityBuilder where - S: Into, + S1: Into, + S2: Into, + S3: Into, + S4: Into, { - CreateOrUpdateModuleIdentityBuilder::new(self, IdentityOperation::Update, Some(etag.into())) + CreateOrUpdateModuleIdentityBuilder::new( + self.clone(), + IdentityOperation::Update, + device_id.into(), + module_id.into(), + managed_by.into(), + authentication, + Some(etag.into()), + ) } /// Create a new device identity diff --git a/sdk/iot_hub/src/service/requests/create_or_update_module_identity.rs b/sdk/iot_hub/src/service/requests/create_or_update_module_identity.rs new file mode 100644 index 0000000000..e12adaf04a --- /dev/null +++ b/sdk/iot_hub/src/service/requests/create_or_update_module_identity.rs @@ -0,0 +1,74 @@ +use crate::service::resources::{identity::IdentityOperation, AuthenticationMechanism}; +use crate::service::responses::ModuleIdentityResponse; +use crate::service::{ServiceClient, API_VERSION}; +use azure_core::error::{Error, ErrorKind}; +use azure_core::headers; +use azure_core::Method; +use serde::Serialize; +use std::convert::TryInto; + +azure_core::operation! { + /// The CreateOrUpdateModuleIdentityBuilder is used to construct a new module identity + /// or the update an existing one. + CreateOrUpdateModuleIdentity, + client: ServiceClient, + operation: IdentityOperation, + device_id: String, + module_id: String, + managed_by: String, + authentication: AuthenticationMechanism, + etag: Option, +} + +impl<'a> CreateOrUpdateModuleIdentityBuilder { + /// Performs the create or update request on the device identity + pub async fn into_future(self) -> CreateOrUpdateModuleIdentity { + Box::pin(async move { + let uri = format!( + "https://{}.azure-devices.net/devices/{}/modules/{}?api-version={}", + self.client.iot_hub_name, self.device_id, self.module_id, API_VERSION + ); + + let mut request = self.client.finalize_request(&uri, Method::Put)?; + + if self.operation == IdentityOperation::Update { + match &self.etag { + Some(etag) => { + request.insert_header(headers::IF_MATCH, format!("\"{}\"", etag)); + } + None => return Err(Error::message(ErrorKind::Other, "etag is not set")), + } + } + + let body = CreateOrUpdateModuleIdentityBody { + authentication: self.authentication, + device_id: self.device_id.as_ref(), + module_id: self.module_id.as_ref(), + managed_by: self.managed_by.as_ref(), + etag: self.etag, + }; + + let body = azure_core::to_json(&body)?; + request.set_body(body); + + self.client + .http_client() + .execute_request_check_status(&request) + .await? + .try_into() + }) + } +} + +pub type CreateOrUpdateModuleIdentityResponse = ModuleIdentityResponse; + +#[derive(Serialize)] +#[serde(rename_all = "camelCase")] +struct CreateOrUpdateModuleIdentityBody<'a, 'b, 'c> { + authentication: AuthenticationMechanism, + device_id: &'a str, + module_id: &'b str, + managed_by: &'c str, + #[serde(skip_serializing_if = "Option::is_none")] + etag: Option, +} diff --git a/sdk/iot_hub/src/service/requests/create_or_update_module_identity_builder.rs b/sdk/iot_hub/src/service/requests/create_or_update_module_identity_builder.rs deleted file mode 100644 index f68d39ea2f..0000000000 --- a/sdk/iot_hub/src/service/requests/create_or_update_module_identity_builder.rs +++ /dev/null @@ -1,91 +0,0 @@ -use crate::service::resources::{identity::IdentityOperation, AuthenticationMechanism}; -use crate::service::responses::ModuleIdentityResponse; -use crate::service::{ServiceClient, API_VERSION}; -use azure_core::error::{Error, ErrorKind}; -use azure_core::headers; -use azure_core::Method; -use serde::Serialize; -use std::convert::TryInto; - -/// The CreateOrUpdateModuleIdentityBuilder is used to construct a new module identity -/// or the update an existing one. -pub struct CreateOrUpdateModuleIdentityBuilder<'a> { - service_client: &'a ServiceClient, - etag: Option, - operation: IdentityOperation, -} - -impl<'a> CreateOrUpdateModuleIdentityBuilder<'a> { - pub(crate) fn new( - service_client: &'a ServiceClient, - operation: IdentityOperation, - etag: Option, - ) -> Self { - Self { - service_client, - etag, - operation, - } - } - - /// Performs the create or update request on the device identity - pub async fn execute( - self, - device_id: S, - module_id: T, - managed_by: U, - authentication: AuthenticationMechanism, - ) -> azure_core::Result - where - S: AsRef, - T: AsRef, - U: AsRef, - { - let uri = format!( - "https://{}.azure-devices.net/devices/{}/modules/{}?api-version={}", - self.service_client.iot_hub_name, - device_id.as_ref(), - module_id.as_ref(), - API_VERSION - ); - - let mut request = self.service_client.finalize_request(&uri, Method::Put)?; - - if self.operation == IdentityOperation::Update { - match &self.etag { - Some(etag) => { - request.insert_header(headers::IF_MATCH, format!("\"{}\"", etag)); - } - None => return Err(Error::message(ErrorKind::Other, "etag is not set")), - } - } - - let body = CreateOrUpdateModuleIdentityBody { - authentication, - device_id: device_id.as_ref(), - module_id: module_id.as_ref(), - managed_by: managed_by.as_ref(), - etag: self.etag, - }; - - let body = azure_core::to_json(&body)?; - request.set_body(body); - - self.service_client - .http_client() - .execute_request_check_status(&request) - .await? - .try_into() - } -} - -#[derive(Serialize)] -#[serde(rename_all = "camelCase")] -struct CreateOrUpdateModuleIdentityBody<'a, 'b, 'c> { - authentication: AuthenticationMechanism, - device_id: &'a str, - module_id: &'b str, - managed_by: &'c str, - #[serde(skip_serializing_if = "Option::is_none")] - etag: Option, -} diff --git a/sdk/iot_hub/src/service/requests/mod.rs b/sdk/iot_hub/src/service/requests/mod.rs index d5ac83108f..33ccface41 100644 --- a/sdk/iot_hub/src/service/requests/mod.rs +++ b/sdk/iot_hub/src/service/requests/mod.rs @@ -1,7 +1,7 @@ mod apply_on_edge_device; mod create_or_update_configuration; mod create_or_update_device_identity; -mod create_or_update_module_identity_builder; +mod create_or_update_module_identity; mod delete_configuration_builder; mod delete_identity_builder; mod get_configuration; @@ -14,7 +14,7 @@ mod update_or_replace_twin_builder; pub use apply_on_edge_device::ApplyOnEdgeDeviceBuilder; pub use create_or_update_configuration::CreateOrUpdateConfigurationBuilder; pub use create_or_update_device_identity::CreateOrUpdateDeviceIdentityBuilder; -pub use create_or_update_module_identity_builder::CreateOrUpdateModuleIdentityBuilder; +pub use create_or_update_module_identity::CreateOrUpdateModuleIdentityBuilder; pub use delete_configuration_builder::DeleteConfigurationBuilder; pub use delete_identity_builder::DeleteIdentityBuilder; pub(crate) use get_configuration::get_configuration; From a17c08ba9635a06b2f34b9a150ee530ed6c2cdba Mon Sep 17 00:00:00 2001 From: Ryan Levick Date: Wed, 27 Jul 2022 10:44:57 +0200 Subject: [PATCH 05/14] Delete --- sdk/iot_hub/src/service/mod.rs | 16 +++--- .../create_or_update_configuration.rs | 2 +- .../create_or_update_module_identity.rs | 2 +- .../service/requests/delete_configuration.rs | 37 +++++++++++++ .../requests/delete_configuration_builder.rs | 44 ---------------- .../src/service/requests/delete_identity.rs | 43 +++++++++++++++ .../requests/delete_identity_builder.rs | 52 ------------------- sdk/iot_hub/src/service/requests/mod.rs | 8 +-- 8 files changed, 92 insertions(+), 112 deletions(-) create mode 100644 sdk/iot_hub/src/service/requests/delete_configuration.rs delete mode 100644 sdk/iot_hub/src/service/requests/delete_configuration_builder.rs create mode 100644 sdk/iot_hub/src/service/requests/delete_identity.rs delete mode 100644 sdk/iot_hub/src/service/requests/delete_identity_builder.rs diff --git a/sdk/iot_hub/src/service/mod.rs b/sdk/iot_hub/src/service/mod.rs index 1a7d9132ca..9ffc71c39f 100644 --- a/sdk/iot_hub/src/service/mod.rs +++ b/sdk/iot_hub/src/service/mod.rs @@ -567,16 +567,12 @@ impl ServiceClient { /// let iot_hub = ServiceClient::from_connection_string(http_client, connection_string, 3600).expect("Failed to create the ServiceClient!"); /// let device = iot_hub.delete_device_identity("some-device-id", "some-etag"); /// ``` - pub fn delete_device_identity( - &self, - device_id: S, - if_match: T, - ) -> DeleteIdentityBuilder<'_> + pub fn delete_device_identity(&self, device_id: S, if_match: T) -> DeleteIdentityBuilder where S: Into, T: Into, { - DeleteIdentityBuilder::new(self, if_match.into(), device_id.into(), None) + DeleteIdentityBuilder::new(self.clone(), if_match.into(), device_id.into(), None) } /// Get the identity of a given module @@ -695,14 +691,14 @@ impl ServiceClient { device_id: S, module_id: T, if_match: U, - ) -> DeleteIdentityBuilder<'_> + ) -> DeleteIdentityBuilder where S: Into, T: Into, U: Into, { DeleteIdentityBuilder::new( - self, + self.clone(), if_match.into(), device_id.into(), Some(module_id.into()), @@ -862,12 +858,12 @@ impl ServiceClient { &self, configuration_id: S, if_match: T, - ) -> DeleteConfigurationBuilder<'_> + ) -> DeleteConfigurationBuilder where S: Into, T: Into, { - DeleteConfigurationBuilder::new(self, if_match.into(), configuration_id.into()) + DeleteConfigurationBuilder::new(self.clone(), if_match.into(), configuration_id.into()) } /// Prepares a request that can be used by any request builders. diff --git a/sdk/iot_hub/src/service/requests/create_or_update_configuration.rs b/sdk/iot_hub/src/service/requests/create_or_update_configuration.rs index c3c46ffaac..9e416acaec 100644 --- a/sdk/iot_hub/src/service/requests/create_or_update_configuration.rs +++ b/sdk/iot_hub/src/service/requests/create_or_update_configuration.rs @@ -24,7 +24,7 @@ azure_core::operation! { impl CreateOrUpdateConfigurationBuilder { /// Performs the create or update request on the device identity - pub async fn into_future(self) -> CreateOrUpdateConfiguration { + pub fn into_future(self) -> CreateOrUpdateConfiguration { Box::pin(async move { let uri = format!( "https://{}.azure-devices.net/configurations/{}?api-version={}", diff --git a/sdk/iot_hub/src/service/requests/create_or_update_module_identity.rs b/sdk/iot_hub/src/service/requests/create_or_update_module_identity.rs index e12adaf04a..038a887997 100644 --- a/sdk/iot_hub/src/service/requests/create_or_update_module_identity.rs +++ b/sdk/iot_hub/src/service/requests/create_or_update_module_identity.rs @@ -22,7 +22,7 @@ azure_core::operation! { impl<'a> CreateOrUpdateModuleIdentityBuilder { /// Performs the create or update request on the device identity - pub async fn into_future(self) -> CreateOrUpdateModuleIdentity { + pub fn into_future(self) -> CreateOrUpdateModuleIdentity { Box::pin(async move { let uri = format!( "https://{}.azure-devices.net/devices/{}/modules/{}?api-version={}", diff --git a/sdk/iot_hub/src/service/requests/delete_configuration.rs b/sdk/iot_hub/src/service/requests/delete_configuration.rs new file mode 100644 index 0000000000..cb63d374a7 --- /dev/null +++ b/sdk/iot_hub/src/service/requests/delete_configuration.rs @@ -0,0 +1,37 @@ +use crate::service::{ServiceClient, API_VERSION}; + +use azure_core::headers; +use azure_core::Method; + +azure_core::operation! { + /// The DeleteConfigurationBuilder is used to construct a request to delete a configuration. + DeleteConfiguration, + client: ServiceClient, + if_match: String, + configuration_id: String, +} + +impl DeleteConfigurationBuilder { + /// Execute the request to delete the configuration. + pub fn into_future(self) -> DeleteConfiguration { + Box::pin(async move { + let uri = format!( + "https://{}.azure-devices.net/configurations/{}?api-version={}", + self.client.iot_hub_name, self.configuration_id, API_VERSION + ); + + let mut request = self.client.finalize_request(&uri, Method::Delete)?; + request.insert_header(headers::IF_MATCH, format!("\"{}\"", &self.if_match)); + + request.set_body(azure_core::EMPTY_BODY); + + self.client + .http_client() + .execute_request_check_status(&request) + .await?; + Ok(()) + }) + } +} + +pub type DeleteConfigurationResponse = (); diff --git a/sdk/iot_hub/src/service/requests/delete_configuration_builder.rs b/sdk/iot_hub/src/service/requests/delete_configuration_builder.rs deleted file mode 100644 index 3411091253..0000000000 --- a/sdk/iot_hub/src/service/requests/delete_configuration_builder.rs +++ /dev/null @@ -1,44 +0,0 @@ -use crate::service::{ServiceClient, API_VERSION}; - -use azure_core::headers; -use azure_core::Method; - -/// The DeleteConfigurationBuilder is used to construct a request to delete a configuration. -pub struct DeleteConfigurationBuilder<'a> { - service_client: &'a ServiceClient, - if_match: String, - configuration_id: String, -} - -impl<'a> DeleteConfigurationBuilder<'a> { - pub(crate) fn new( - service_client: &'a ServiceClient, - if_match: String, - configuration_id: String, - ) -> Self { - Self { - service_client, - if_match, - configuration_id, - } - } - - /// Execute the request to delete the configuration. - pub async fn execute(&self) -> azure_core::Result<()> { - let uri = format!( - "https://{}.azure-devices.net/configurations/{}?api-version={}", - self.service_client.iot_hub_name, self.configuration_id, API_VERSION - ); - - let mut request = self.service_client.finalize_request(&uri, Method::Delete)?; - request.insert_header(headers::IF_MATCH, format!("\"{}\"", &self.if_match)); - - request.set_body(azure_core::EMPTY_BODY); - - self.service_client - .http_client() - .execute_request_check_status(&request) - .await?; - Ok(()) - } -} diff --git a/sdk/iot_hub/src/service/requests/delete_identity.rs b/sdk/iot_hub/src/service/requests/delete_identity.rs new file mode 100644 index 0000000000..207e35c213 --- /dev/null +++ b/sdk/iot_hub/src/service/requests/delete_identity.rs @@ -0,0 +1,43 @@ +use crate::service::{ServiceClient, API_VERSION}; +use azure_core::headers; +use azure_core::Method; + +azure_core::operation! { + /// The DeleteIdentityBuilder is used to construct a request to delete a module or device identity. + DeleteIdentity, + client: ServiceClient, + if_match: String, + device_id: String, + module_id: Option, +} + +impl DeleteIdentityBuilder { + /// Execute the request to delete the module or device identity. + pub fn into_future(self) -> DeleteIdentity { + Box::pin(async move { + let uri = match &self.module_id { + Some(module_id) => format!( + "https://{}.azure-devices.net/devices/{}/modules/{}?api-version={}", + self.client.iot_hub_name, self.device_id, module_id, API_VERSION + ), + None => format!( + "https://{}.azure-devices.net/devices/{}?api-version={}", + self.client.iot_hub_name, self.device_id, API_VERSION + ), + }; + + let mut request = self.client.finalize_request(&uri, Method::Delete)?; + request.insert_header(headers::IF_MATCH, format!("\"{}\"", &self.if_match)); + + request.set_body(azure_core::EMPTY_BODY); + + self.client + .http_client() + .execute_request_check_status(&request) + .await?; + Ok(()) + }) + } +} + +pub type DeleteIdentityResponse = (); diff --git a/sdk/iot_hub/src/service/requests/delete_identity_builder.rs b/sdk/iot_hub/src/service/requests/delete_identity_builder.rs deleted file mode 100644 index 7ca664cedd..0000000000 --- a/sdk/iot_hub/src/service/requests/delete_identity_builder.rs +++ /dev/null @@ -1,52 +0,0 @@ -use crate::service::{ServiceClient, API_VERSION}; -use azure_core::headers; -use azure_core::Method; - -/// The DeleteIdentityBuilder is used to construct a request to delete a module or device identity. -pub struct DeleteIdentityBuilder<'a> { - service_client: &'a ServiceClient, - if_match: String, - device_id: String, - module_id: Option, -} - -impl<'a> DeleteIdentityBuilder<'a> { - pub(crate) fn new( - service_client: &'a ServiceClient, - if_match: String, - device_id: String, - module_id: Option, - ) -> Self { - Self { - service_client, - if_match, - device_id, - module_id, - } - } - - /// Execute the request to delete the module or device identity. - pub async fn execute(&self) -> azure_core::Result<()> { - let uri = match &self.module_id { - Some(module_id) => format!( - "https://{}.azure-devices.net/devices/{}/modules/{}?api-version={}", - self.service_client.iot_hub_name, self.device_id, module_id, API_VERSION - ), - None => format!( - "https://{}.azure-devices.net/devices/{}?api-version={}", - self.service_client.iot_hub_name, self.device_id, API_VERSION - ), - }; - - let mut request = self.service_client.finalize_request(&uri, Method::Delete)?; - request.insert_header(headers::IF_MATCH, format!("\"{}\"", &self.if_match)); - - request.set_body(azure_core::EMPTY_BODY); - - self.service_client - .http_client() - .execute_request_check_status(&request) - .await?; - Ok(()) - } -} diff --git a/sdk/iot_hub/src/service/requests/mod.rs b/sdk/iot_hub/src/service/requests/mod.rs index 33ccface41..cd7666ed9b 100644 --- a/sdk/iot_hub/src/service/requests/mod.rs +++ b/sdk/iot_hub/src/service/requests/mod.rs @@ -2,8 +2,8 @@ mod apply_on_edge_device; mod create_or_update_configuration; mod create_or_update_device_identity; mod create_or_update_module_identity; -mod delete_configuration_builder; -mod delete_identity_builder; +mod delete_configuration; +mod delete_identity; mod get_configuration; mod get_identity; mod get_twin; @@ -15,8 +15,8 @@ pub use apply_on_edge_device::ApplyOnEdgeDeviceBuilder; pub use create_or_update_configuration::CreateOrUpdateConfigurationBuilder; pub use create_or_update_device_identity::CreateOrUpdateDeviceIdentityBuilder; pub use create_or_update_module_identity::CreateOrUpdateModuleIdentityBuilder; -pub use delete_configuration_builder::DeleteConfigurationBuilder; -pub use delete_identity_builder::DeleteIdentityBuilder; +pub use delete_configuration::DeleteConfigurationBuilder; +pub use delete_identity::DeleteIdentityBuilder; pub(crate) use get_configuration::get_configuration; pub(crate) use get_identity::get_identity; pub(crate) use get_twin::get_twin; From 85ac5d80bf798225763cfcfb6f894fd14c67c82c Mon Sep 17 00:00:00 2001 From: Ryan Levick Date: Wed, 27 Jul 2022 10:53:11 +0200 Subject: [PATCH 06/14] GetConfiguration --- sdk/iot_hub/src/service/mod.rs | 23 ++++---- .../src/service/requests/get_configuration.rs | 58 ++++++++++--------- sdk/iot_hub/src/service/requests/mod.rs | 2 +- 3 files changed, 42 insertions(+), 41 deletions(-) diff --git a/sdk/iot_hub/src/service/mod.rs b/sdk/iot_hub/src/service/mod.rs index 9ffc71c39f..3d7a4736e4 100644 --- a/sdk/iot_hub/src/service/mod.rs +++ b/sdk/iot_hub/src/service/mod.rs @@ -14,17 +14,17 @@ pub mod resources; pub mod responses; use crate::service::requests::{ - get_configuration, get_identity, get_twin, ApplyOnEdgeDeviceBuilder, - CreateOrUpdateConfigurationBuilder, CreateOrUpdateDeviceIdentityBuilder, - CreateOrUpdateModuleIdentityBuilder, DeleteConfigurationBuilder, DeleteIdentityBuilder, - InvokeMethodBuilder, QueryBuilder, UpdateOrReplaceTwinBuilder, + get_identity, get_twin, ApplyOnEdgeDeviceBuilder, CreateOrUpdateConfigurationBuilder, + CreateOrUpdateDeviceIdentityBuilder, CreateOrUpdateModuleIdentityBuilder, + DeleteConfigurationBuilder, DeleteIdentityBuilder, InvokeMethodBuilder, QueryBuilder, + UpdateOrReplaceTwinBuilder, }; use crate::service::resources::identity::IdentityOperation; use crate::service::responses::{ - ConfigurationResponse, DeviceIdentityResponse, DeviceTwinResponse, ModuleIdentityResponse, - ModuleTwinResponse, MultipleConfigurationResponse, + DeviceIdentityResponse, DeviceTwinResponse, ModuleIdentityResponse, ModuleTwinResponse, }; +use self::requests::GetConfigurationBuilder; use self::resources::{AuthenticationMechanism, Status}; /// The API version to use for any requests @@ -749,14 +749,11 @@ impl ServiceClient { /// let iot_hub = ServiceClient::from_connection_string(http_client, connection_string, 3600).expect("Failed to create the ServiceClient!"); /// let device = iot_hub.get_configuration("some-configuration"); /// ``` - pub async fn get_configuration( - &self, - configuration_id: S, - ) -> azure_core::Result + pub async fn get_configuration(&self, configuration_id: S) -> GetConfigurationBuilder where S: Into, { - get_configuration(self, Some(configuration_id.into())).await + GetConfigurationBuilder::new(self.clone()).configuration_id(configuration_id.into()) } /// Get all configurations @@ -770,8 +767,8 @@ impl ServiceClient { /// let iot_hub = ServiceClient::from_connection_string(http_client, connection_string, 3600).expect("Failed to create the ServiceClient!"); /// let device = iot_hub.get_configurations(); /// ``` - pub async fn get_configurations(&self) -> azure_core::Result { - get_configuration(self, None).await + pub fn get_configurations(&self) -> GetConfigurationBuilder { + GetConfigurationBuilder::new(self.clone()) } /// Create a new configuration. diff --git a/sdk/iot_hub/src/service/requests/get_configuration.rs b/sdk/iot_hub/src/service/requests/get_configuration.rs index 69994207a3..96a7ed9bef 100644 --- a/sdk/iot_hub/src/service/requests/get_configuration.rs +++ b/sdk/iot_hub/src/service/requests/get_configuration.rs @@ -1,33 +1,37 @@ use crate::service::{ServiceClient, API_VERSION}; -use azure_core::error::Error; use azure_core::Method; -use std::convert::{TryFrom, TryInto}; -/// Execute the request to get the configuration of a given identifier. -pub(crate) async fn get_configuration( - service_client: &ServiceClient, - configuration_id: Option, -) -> azure_core::Result -where - T: TryFrom, -{ - let uri = match configuration_id { - Some(val) => format!( - "https://{}.azure-devices.net/configurations/{}?api-version={}", - service_client.iot_hub_name, val, API_VERSION - ), - None => format!( - "https://{}.azure-devices.net/configurations?api-version={}", - service_client.iot_hub_name, API_VERSION - ), - }; +azure_core::operation! { + GetConfiguration, + client: ServiceClient, + ?configuration_id: String - let mut request = service_client.finalize_request(&uri, Method::Get)?; - request.set_body(azure_core::EMPTY_BODY); +} + +impl GetConfigurationBuilder { + /// Execute the request to get the configuration of a given identifier. + pub fn into_future(self) -> GetConfiguration { + Box::pin(async move { + let uri = match self.configuration_id { + Some(val) => format!( + "https://{}.azure-devices.net/configurations/{}?api-version={}", + self.client.iot_hub_name, val, API_VERSION + ), + None => format!( + "https://{}.azure-devices.net/configurations?api-version={}", + self.client.iot_hub_name, API_VERSION + ), + }; - service_client - .http_client() - .execute_request_check_status(&request) - .await? - .try_into() + let mut request = self.client.finalize_request(&uri, Method::Get)?; + request.set_body(azure_core::EMPTY_BODY); + + self.client + .http_client() + .execute_request_check_status(&request) + .await + }) + } } + +pub type GetConfigurationResponse = crate::service::CollectedResponse; diff --git a/sdk/iot_hub/src/service/requests/mod.rs b/sdk/iot_hub/src/service/requests/mod.rs index cd7666ed9b..b04f0d216a 100644 --- a/sdk/iot_hub/src/service/requests/mod.rs +++ b/sdk/iot_hub/src/service/requests/mod.rs @@ -17,7 +17,7 @@ pub use create_or_update_device_identity::CreateOrUpdateDeviceIdentityBuilder; pub use create_or_update_module_identity::CreateOrUpdateModuleIdentityBuilder; pub use delete_configuration::DeleteConfigurationBuilder; pub use delete_identity::DeleteIdentityBuilder; -pub(crate) use get_configuration::get_configuration; +pub(crate) use get_configuration::GetConfigurationBuilder; pub(crate) use get_identity::get_identity; pub(crate) use get_twin::get_twin; pub use invoke_method_builder::InvokeMethodBuilder; From b8fa3c7832f541200b6e526bb08910b01fa7b201 Mon Sep 17 00:00:00 2001 From: Ryan Levick Date: Wed, 27 Jul 2022 10:59:35 +0200 Subject: [PATCH 07/14] InvokeMethod --- sdk/iot_hub/src/service/mod.rs | 12 +- .../src/service/requests/invoke_method.rs | 87 ++++++++++++ .../service/requests/invoke_method_builder.rs | 131 ------------------ sdk/iot_hub/src/service/requests/mod.rs | 4 +- 4 files changed, 97 insertions(+), 137 deletions(-) create mode 100644 sdk/iot_hub/src/service/requests/invoke_method.rs delete mode 100644 sdk/iot_hub/src/service/requests/invoke_method_builder.rs diff --git a/sdk/iot_hub/src/service/mod.rs b/sdk/iot_hub/src/service/mod.rs index 3d7a4736e4..111c4e2b3b 100644 --- a/sdk/iot_hub/src/service/mod.rs +++ b/sdk/iot_hub/src/service/mod.rs @@ -262,6 +262,7 @@ impl ServiceClient { /// ``` pub fn create_device_method( &self, + payload: serde_json::Value, device_id: S, method_name: T, response_time_out: u64, @@ -272,12 +273,13 @@ impl ServiceClient { T: Into, { InvokeMethodBuilder::new( - self, + self.clone(), + payload, device_id.into(), None, method_name.into(), - connect_time_out, response_time_out, + connect_time_out, ) } @@ -294,6 +296,7 @@ impl ServiceClient { /// ``` pub fn create_module_method( &self, + payload: serde_json::Value, device_id: S, module_id: T, method_name: U, @@ -306,12 +309,13 @@ impl ServiceClient { U: Into, { InvokeMethodBuilder::new( - self, + self.clone(), + payload, device_id.into(), Some(module_id.into()), method_name.into(), - connect_time_out, response_time_out, + connect_time_out, ) } diff --git a/sdk/iot_hub/src/service/requests/invoke_method.rs b/sdk/iot_hub/src/service/requests/invoke_method.rs new file mode 100644 index 0000000000..9093b671b3 --- /dev/null +++ b/sdk/iot_hub/src/service/requests/invoke_method.rs @@ -0,0 +1,87 @@ +use crate::service::responses::InvokeMethodResponse; +use crate::service::{ServiceClient, API_VERSION}; +use azure_core::Method; +use serde::Serialize; +use std::convert::TryInto; + +azure_core::operation! { + /// The InvokeMethodBuilder is used for constructing the request to + /// invoke a module or device method. + InvokeMethod, + client: ServiceClient, + payload: serde_json::Value, + device_id: String, + module_id: Option, + method_name: String, + response_time_out: u64, + connect_time_out: u64, +} + +impl InvokeMethodBuilder { + /// Invoke the DirectMethod + /// + /// Either a module method, or device method is invoked based on the + /// way the DirectMethod was created. On invocation a DirectMethodResponse + /// is returned. This does not mean the invocation was successfull. The status + /// code within the DirectMethodResponse should still be verified. + /// + /// # Examples + /// ``` + /// # use std::sync::Arc; + /// # use azure_core::HttpClient; + /// use azure_iot_hub::service::ServiceClient; + /// # let http_client = azure_core::new_http_client(); + /// + /// let service = ServiceClient::from_sas_token(http_client, "some-iot-hub", "sas_token"); + /// let great_method = service.create_device_method( + /// "SomeDeviceId", + /// "GreatMethod", + /// 100, + /// 60 + /// ); + /// + /// great_method.execute(serde_json::json!({"hello": "world"})); + /// ``` + pub async fn into_future(self) -> InvokeMethod { + Box::pin(async move { + let uri = match &self.module_id { + Some(module_id_value) => format!( + "https://{}.azure-devices.net/twins/{}/modules/{}/methods?api-version={}", + self.client.iot_hub_name, self.device_id, module_id_value, API_VERSION + ), + None => format!( + "https://{}.azure-devices.net/twins/{}/methods?api-version={}", + self.client.iot_hub_name, self.device_id, API_VERSION + ), + }; + + let mut request = self.client.finalize_request(&uri, Method::Post)?; + let method = InvokeMethodBody { + connect_timeout_in_seconds: self.connect_time_out, + method_name: &self.method_name, + payload: self.payload, + response_timeout_in_seconds: self.response_time_out, + }; + + let body = azure_core::to_json(&method)?; + + request.set_body(body); + + self.client + .http_client() + .execute_request_check_status(&request) + .await? + .try_into() + }) + } +} + +/// Body for the InvokeMethod request +#[derive(Serialize, Debug)] +#[serde(rename_all = "camelCase")] +struct InvokeMethodBody<'a> { + connect_timeout_in_seconds: u64, + method_name: &'a str, + payload: serde_json::Value, + response_timeout_in_seconds: u64, +} diff --git a/sdk/iot_hub/src/service/requests/invoke_method_builder.rs b/sdk/iot_hub/src/service/requests/invoke_method_builder.rs deleted file mode 100644 index 70ecc5aed6..0000000000 --- a/sdk/iot_hub/src/service/requests/invoke_method_builder.rs +++ /dev/null @@ -1,131 +0,0 @@ -use crate::service::responses::InvokeMethodResponse; -use crate::service::{ServiceClient, API_VERSION}; -use azure_core::Method; -use serde::Serialize; -use std::convert::TryInto; - -/// The InvokeMethodBuilder is used for constructing the request to -/// invoke a module or device method. -pub struct InvokeMethodBuilder<'a> { - iot_hub_service: &'a ServiceClient, - device_id: String, - module_id: Option, - method_name: String, - connect_time_out: u64, - response_time_out: u64, -} - -impl<'a> InvokeMethodBuilder<'a> { - /// Create a new DirectMethod - pub(crate) fn new( - iot_hub_service: &'a ServiceClient, - device_id: String, - module_id: Option, - method_name: String, - response_time_out: u64, - connect_time_out: u64, - ) -> Self { - Self { - iot_hub_service, - device_id, - module_id, - method_name, - connect_time_out, - response_time_out, - } - } - - /// Invoke the DirectMethod - /// - /// Either a module method, or device method is invoked based on the - /// way the DirectMethod was created. On invocation a DirectMethodResponse - /// is returned. This does not mean the invocation was successfull. The status - /// code within the DirectMethodResponse should still be verified. - /// - /// # Examples - /// ``` - /// # use std::sync::Arc; - /// # use azure_core::HttpClient; - /// use azure_iot_hub::service::ServiceClient; - /// # let http_client = azure_core::new_http_client(); - /// - /// let service = ServiceClient::from_sas_token(http_client, "some-iot-hub", "sas_token"); - /// let great_method = service.create_device_method( - /// "SomeDeviceId", - /// "GreatMethod", - /// 100, - /// 60 - /// ); - /// - /// great_method.execute(serde_json::json!({"hello": "world"})); - /// ``` - pub async fn execute( - &self, - payload: serde_json::Value, - ) -> azure_core::Result { - let uri = match &self.module_id { - Some(module_id_value) => format!( - "https://{}.azure-devices.net/twins/{}/modules/{}/methods?api-version={}", - self.iot_hub_service.iot_hub_name, self.device_id, module_id_value, API_VERSION - ), - None => format!( - "https://{}.azure-devices.net/twins/{}/methods?api-version={}", - self.iot_hub_service.iot_hub_name, self.device_id, API_VERSION - ), - }; - - let mut request = self.iot_hub_service.finalize_request(&uri, Method::Post)?; - let method = InvokeMethodBody { - connect_timeout_in_seconds: self.connect_time_out, - method_name: &self.method_name, - payload, - response_timeout_in_seconds: self.response_time_out, - }; - - let body = azure_core::to_json(&method)?; - - request.set_body(body); - - self.iot_hub_service - .http_client() - .execute_request_check_status(&request) - .await? - .try_into() - } -} - -/// Body for the InvokeMethod request -#[derive(Serialize, Debug)] -#[serde(rename_all = "camelCase")] -struct InvokeMethodBody<'a> { - connect_timeout_in_seconds: u64, - method_name: &'a str, - payload: serde_json::Value, - response_timeout_in_seconds: u64, -} - -#[cfg(test)] -mod tests { - use crate::service::ServiceClient; - - #[test] - fn directmethod_new_should_succeed() { - use crate::service::InvokeMethodBuilder; - - let http_client = azure_core::new_http_client(); - let service: ServiceClient = ServiceClient::from_sas_token(http_client, "test", "test"); - let direct_method = InvokeMethodBuilder::new( - &service, - "SomeDevice".to_string(), - None, - "GreatMethod".to_string(), - 20, - 10, - ); - assert_eq!(direct_method.device_id, "SomeDevice"); - assert_eq!(direct_method.module_id, None); - assert_eq!(direct_method.method_name, "GreatMethod"); - assert_eq!(direct_method.connect_time_out, 10); - assert_eq!(direct_method.response_time_out, 20); - } -} diff --git a/sdk/iot_hub/src/service/requests/mod.rs b/sdk/iot_hub/src/service/requests/mod.rs index b04f0d216a..e7784cb7ec 100644 --- a/sdk/iot_hub/src/service/requests/mod.rs +++ b/sdk/iot_hub/src/service/requests/mod.rs @@ -7,7 +7,7 @@ mod delete_identity; mod get_configuration; mod get_identity; mod get_twin; -mod invoke_method_builder; +mod invoke_method; mod query_builder; mod update_or_replace_twin_builder; @@ -20,6 +20,6 @@ pub use delete_identity::DeleteIdentityBuilder; pub(crate) use get_configuration::GetConfigurationBuilder; pub(crate) use get_identity::get_identity; pub(crate) use get_twin::get_twin; -pub use invoke_method_builder::InvokeMethodBuilder; +pub use invoke_method::InvokeMethodBuilder; pub use query_builder::QueryBuilder; pub use update_or_replace_twin_builder::UpdateOrReplaceTwinBuilder; From dfde895c6e48b4d687b7eb0d13be4e80e8f3f5ab Mon Sep 17 00:00:00 2001 From: Ryan Levick Date: Wed, 27 Jul 2022 11:03:38 +0200 Subject: [PATCH 08/14] Query --- sdk/iot_hub/src/service/mod.rs | 7 +- sdk/iot_hub/src/service/requests/mod.rs | 4 +- sdk/iot_hub/src/service/requests/query.rs | 61 +++++++++++++++ .../src/service/requests/query_builder.rs | 74 ------------------- 4 files changed, 68 insertions(+), 78 deletions(-) create mode 100644 sdk/iot_hub/src/service/requests/query.rs delete mode 100644 sdk/iot_hub/src/service/requests/query_builder.rs diff --git a/sdk/iot_hub/src/service/mod.rs b/sdk/iot_hub/src/service/mod.rs index 111c4e2b3b..63b64af8da 100644 --- a/sdk/iot_hub/src/service/mod.rs +++ b/sdk/iot_hub/src/service/mod.rs @@ -720,8 +720,11 @@ impl ServiceClient { /// let iot_hub = ServiceClient::from_connection_string(http_client, connection_string, 3600).expect("Failed to create the ServiceClient!"); /// let query_builder = iot_hub.query(); /// ``` - pub fn query(&self) -> QueryBuilder<'_> { - QueryBuilder::new(self) + pub fn query(&self, query: Q) -> QueryBuilder + where + Q: Into, + { + QueryBuilder::new(self.clone(), query.into()) } /// Apply configuration on an Edge device diff --git a/sdk/iot_hub/src/service/requests/mod.rs b/sdk/iot_hub/src/service/requests/mod.rs index e7784cb7ec..0b854da245 100644 --- a/sdk/iot_hub/src/service/requests/mod.rs +++ b/sdk/iot_hub/src/service/requests/mod.rs @@ -8,7 +8,7 @@ mod get_configuration; mod get_identity; mod get_twin; mod invoke_method; -mod query_builder; +mod query; mod update_or_replace_twin_builder; pub use apply_on_edge_device::ApplyOnEdgeDeviceBuilder; @@ -21,5 +21,5 @@ pub(crate) use get_configuration::GetConfigurationBuilder; pub(crate) use get_identity::get_identity; pub(crate) use get_twin::get_twin; pub use invoke_method::InvokeMethodBuilder; -pub use query_builder::QueryBuilder; +pub use query::QueryBuilder; pub use update_or_replace_twin_builder::UpdateOrReplaceTwinBuilder; diff --git a/sdk/iot_hub/src/service/requests/query.rs b/sdk/iot_hub/src/service/requests/query.rs new file mode 100644 index 0000000000..b2f2cb1c37 --- /dev/null +++ b/sdk/iot_hub/src/service/requests/query.rs @@ -0,0 +1,61 @@ +#![allow(missing_docs)] + +use crate::service::{responses::QueryResponse, ServiceClient, API_VERSION}; +use azure_core::prelude::*; +use azure_core::Method; +use serde::Serialize; +use std::convert::TryInto; + +/// Body for the Query request +#[derive(Serialize, Debug)] +struct QueryBody { + query: String, +} + +azure_core::operation! { + /// Builder for creating queries + Query, + client: ServiceClient, + query: String, + ?max_item_count: MaxItemCount, + ?continuation: Continuation +} + +impl QueryBuilder { + /// Invoke a qiven query on the IoT Hub + /// + /// ``` + /// use std::sync::Arc; + /// use azure_core::HttpClient; + /// use azure_iot_hub::service::ServiceClient; + /// + /// # let http_client = azure_core::new_http_client(); + /// # let connection_string = "HostName=cool-iot-hub.azure-devices.net;SharedAccessKeyName=iot_hubowner;SharedAccessKey=YSB2ZXJ5IHNlY3VyZSBrZXkgaXMgaW1wb3J0YW50Cg=="; + /// let iot_hub = ServiceClient::from_connection_string(http_client, connection_string, 3600).expect("Failed to create the ServiceClient!"); + /// let query_builder = iot_hub.query().max_item_count(1).continuation("some_token").execute("SELECT * FROM devices"); + /// ``` + pub fn into_future(self) -> Query { + Box::pin(async move { + let uri = format!( + "https://{}.azure-devices.net/devices/query?api-version={}", + self.client.iot_hub_name, API_VERSION + ); + + let query_body = QueryBody { + query: self.query.into(), + }; + let body = azure_core::to_json(&query_body)?; + + let mut request = self.client.finalize_request(&uri, Method::Post)?; + request.add_optional_header(&self.continuation); + request.add_mandatory_header(&self.max_item_count.unwrap_or_default()); + request.set_body(body); + + self.client + .http_client() + .execute_request_check_status(&request) + .await? + .try_into() + }) + } +} diff --git a/sdk/iot_hub/src/service/requests/query_builder.rs b/sdk/iot_hub/src/service/requests/query_builder.rs deleted file mode 100644 index 3070895693..0000000000 --- a/sdk/iot_hub/src/service/requests/query_builder.rs +++ /dev/null @@ -1,74 +0,0 @@ -#![allow(missing_docs)] - -use crate::service::{responses::QueryResponse, ServiceClient, API_VERSION}; -use azure_core::prelude::*; -use azure_core::Method; -use serde::Serialize; -use std::convert::TryInto; - -/// Body for the Query request -#[derive(Serialize, Debug)] -struct QueryBody { - query: String, -} - -/// Builder for creating queries -pub struct QueryBuilder<'a> { - service_client: &'a ServiceClient, - max_item_count: MaxItemCount, - continuation: Option, -} - -impl<'a> QueryBuilder<'a> { - /// Create a new query struct - pub(crate) fn new(service_client: &'a ServiceClient) -> Self { - Self { - service_client, - max_item_count: MaxItemCount::new(-1), - continuation: None, - } - } - - azure_core::setters! { - max_item_count: i32 => MaxItemCount::new(max_item_count), - continuation: Continuation => Some(continuation), - } - - /// Invoke a qiven query on the IoT Hub - /// - /// ``` - /// use std::sync::Arc; - /// use azure_core::HttpClient; - /// use azure_iot_hub::service::ServiceClient; - /// - /// # let http_client = azure_core::new_http_client(); - /// # let connection_string = "HostName=cool-iot-hub.azure-devices.net;SharedAccessKeyName=iot_hubowner;SharedAccessKey=YSB2ZXJ5IHNlY3VyZSBrZXkgaXMgaW1wb3J0YW50Cg=="; - /// let iot_hub = ServiceClient::from_connection_string(http_client, connection_string, 3600).expect("Failed to create the ServiceClient!"); - /// let query_builder = iot_hub.query().max_item_count(1).continuation("some_token").execute("SELECT * FROM devices"); - /// ``` - pub async fn execute(self, query: S) -> azure_core::Result - where - S: Into, - { - let uri = format!( - "https://{}.azure-devices.net/devices/query?api-version={}", - self.service_client.iot_hub_name, API_VERSION - ); - - let query_body = QueryBody { - query: query.into(), - }; - let body = azure_core::to_json(&query_body)?; - - let mut request = self.service_client.finalize_request(&uri, Method::Post)?; - request.add_optional_header(&self.continuation); - request.add_mandatory_header(&self.max_item_count); - request.set_body(body); - - self.service_client - .http_client() - .execute_request_check_status(&request) - .await? - .try_into() - } -} From 3f32aaf031b9aeda6cd58536a21e394a5e51c602 Mon Sep 17 00:00:00 2001 From: Ryan Levick Date: Wed, 27 Jul 2022 13:57:27 +0200 Subject: [PATCH 09/14] GetIdentity --- sdk/iot_hub/src/service/mod.rs | 128 ++----------- .../src/service/requests/get_identity.rs | 55 +++--- sdk/iot_hub/src/service/requests/mod.rs | 8 +- .../requests/update_or_replace_twin.rs | 108 +++++++++++ .../update_or_replace_twin_builder.rs | 175 ------------------ 5 files changed, 159 insertions(+), 315 deletions(-) create mode 100644 sdk/iot_hub/src/service/requests/update_or_replace_twin.rs delete mode 100644 sdk/iot_hub/src/service/requests/update_or_replace_twin_builder.rs diff --git a/sdk/iot_hub/src/service/mod.rs b/sdk/iot_hub/src/service/mod.rs index 63b64af8da..a24328e43d 100644 --- a/sdk/iot_hub/src/service/mod.rs +++ b/sdk/iot_hub/src/service/mod.rs @@ -14,15 +14,13 @@ pub mod resources; pub mod responses; use crate::service::requests::{ - get_identity, get_twin, ApplyOnEdgeDeviceBuilder, CreateOrUpdateConfigurationBuilder, + get_twin, ApplyOnEdgeDeviceBuilder, CreateOrUpdateConfigurationBuilder, CreateOrUpdateDeviceIdentityBuilder, CreateOrUpdateModuleIdentityBuilder, - DeleteConfigurationBuilder, DeleteIdentityBuilder, InvokeMethodBuilder, QueryBuilder, - UpdateOrReplaceTwinBuilder, + DeleteConfigurationBuilder, DeleteIdentityBuilder, GetIdentityBuilder, InvokeMethodBuilder, + QueryBuilder, UpdateOrReplaceTwinBuilder, }; use crate::service::resources::identity::IdentityOperation; -use crate::service::responses::{ - DeviceIdentityResponse, DeviceTwinResponse, ModuleIdentityResponse, ModuleTwinResponse, -}; +use crate::service::responses::{DeviceTwinResponse, ModuleTwinResponse}; use self::requests::GetConfigurationBuilder; use self::resources::{AuthenticationMechanism, Status}; @@ -379,21 +377,13 @@ impl ServiceClient { /// .properties(serde_json::json!({"PropertyName": "PropertyValue"})) /// .execute(); /// ``` - pub fn update_module_twin( - &self, - device_id: S, - module_id: T, - ) -> UpdateOrReplaceTwinBuilder<'_, ModuleTwinResponse> + pub fn update_module_twin(&self, device_id: S, module_id: T) -> UpdateOrReplaceTwinBuilder where S: Into, T: Into, { - UpdateOrReplaceTwinBuilder::new( - self, - device_id.into(), - Some(module_id.into()), - Method::Patch, - ) + UpdateOrReplaceTwinBuilder::new(self.clone(), device_id.into(), Method::Patch) + .module_id(module_id.into()) } /// Replace the module twin of a given device and module @@ -414,12 +404,13 @@ impl ServiceClient { &self, device_id: S, module_id: T, - ) -> UpdateOrReplaceTwinBuilder<'_, ModuleTwinResponse> + ) -> UpdateOrReplaceTwinBuilder where S: Into, T: Into, { - UpdateOrReplaceTwinBuilder::new(self, device_id.into(), Some(module_id.into()), Method::Put) + UpdateOrReplaceTwinBuilder::new(self.clone(), device_id.into(), Method::Put) + .module_id(module_id.into()) } /// Update the device twin of a given device @@ -436,14 +427,11 @@ impl ServiceClient { /// .properties(serde_json::json!({"PropertyName": "PropertyValue"})) /// .execute(); /// ``` - pub fn update_device_twin( - &self, - device_id: S, - ) -> UpdateOrReplaceTwinBuilder<'_, DeviceTwinResponse> + pub fn update_device_twin(&self, device_id: S) -> UpdateOrReplaceTwinBuilder where S: Into, { - UpdateOrReplaceTwinBuilder::new(self, device_id.into(), None, Method::Patch) + UpdateOrReplaceTwinBuilder::new(self.clone(), device_id.into(), Method::Patch) } /// Replace the device twin of a given device @@ -460,14 +448,11 @@ impl ServiceClient { /// .properties(serde_json::json!({"PropertyName": "PropertyValue"})) /// .execute(); /// ``` - pub fn replace_device_twin( - &self, - device_id: S, - ) -> UpdateOrReplaceTwinBuilder<'_, DeviceTwinResponse> + pub fn replace_device_twin(&self, device_id: S) -> UpdateOrReplaceTwinBuilder where S: Into, { - UpdateOrReplaceTwinBuilder::new(self, device_id.into(), None, Method::Put) + UpdateOrReplaceTwinBuilder::new(self.clone(), device_id.into(), Method::Put) } /// Get the identity of a given device @@ -481,14 +466,11 @@ impl ServiceClient { /// let iot_hub = ServiceClient::from_connection_string(http_client, connection_string, 3600).expect("Failed to create the ServiceClient!"); /// let device = iot_hub.get_device_identity("some-device"); /// ``` - pub async fn get_device_identity( - &self, - device_id: S, - ) -> azure_core::Result + pub fn get_device_identity(&self, device_id: S) -> GetIdentityBuilder where S: Into, { - get_identity(self, device_id.into(), None).await + GetIdentityBuilder::new(self.clone(), device_id.into()) } /// Create a new device identity @@ -590,16 +572,12 @@ impl ServiceClient { /// let iot_hub = ServiceClient::from_connection_string(http_client, connection_string, 3600).expect("Failed to create the ServiceClient!"); /// let device = iot_hub.get_module_identity("some-device", "some-module"); /// ``` - pub async fn get_module_identity( - &self, - device_id: S, - module_id: T, - ) -> azure_core::Result + pub fn get_module_identity(&self, device_id: S, module_id: T) -> GetIdentityBuilder where S: Into, T: Into, { - get_identity(self, device_id.into(), Some(module_id.into())).await + GetIdentityBuilder::new(self.clone(), device_id.into()).module_id(module_id) } /// Create a new module identity @@ -756,7 +734,7 @@ impl ServiceClient { /// let iot_hub = ServiceClient::from_connection_string(http_client, connection_string, 3600).expect("Failed to create the ServiceClient!"); /// let device = iot_hub.get_configuration("some-configuration"); /// ``` - pub async fn get_configuration(&self, configuration_id: S) -> GetConfigurationBuilder + pub fn get_configuration(&self, configuration_id: S) -> GetConfigurationBuilder where S: Into, { @@ -931,72 +909,4 @@ mod tests { let _ = ServiceClient::from_connection_string(http_client, "HostName=cool-iot-hub.azure-devices.net;SharedAccessKey=YSB2ZXJ5IHNlY3VyZSBrZXkgaXMgaW1wb3J0YW50Cg==", 3600).is_err(); Ok(()) } - - #[test] - fn update_module_twin_should_create_builder() -> Result<(), Box> { - use crate::service::ServiceClient; - let http_client = azure_core::new_http_client(); - - let connection_string = "HostName=cool-iot-hub.azure-devices.net;SharedAccessKeyName=iot_hubowner;SharedAccessKey=YSB2ZXJ5IHNlY3VyZSBrZXkgaXMgaW1wb3J0YW50Cg=="; - let service_client = - ServiceClient::from_connection_string(http_client, connection_string, 3600)?; - - let builder = service_client.update_module_twin("deviceid", "moduleid"); - assert_eq!(builder.device_id, "deviceid".to_string()); - assert_eq!(builder.module_id, Some("moduleid".to_string())); - assert_eq!(builder.method, azure_core::Method::Patch); - - Ok(()) - } - - #[test] - fn replace_module_twin_should_create_builder() -> Result<(), Box> { - use crate::service::ServiceClient; - let http_client = azure_core::new_http_client(); - - let connection_string = "HostName=cool-iot-hub.azure-devices.net;SharedAccessKeyName=iot_hubowner;SharedAccessKey=YSB2ZXJ5IHNlY3VyZSBrZXkgaXMgaW1wb3J0YW50Cg=="; - let service_client = - ServiceClient::from_connection_string(http_client, connection_string, 3600)?; - - let builder = service_client.replace_module_twin("deviceid", "moduleid"); - assert_eq!(builder.device_id, "deviceid".to_string()); - assert_eq!(builder.module_id, Some("moduleid".to_string())); - assert_eq!(builder.method, azure_core::Method::Put); - - Ok(()) - } - - #[test] - fn update_device_twin_should_create_builder() -> Result<(), Box> { - use crate::service::ServiceClient; - let http_client = azure_core::new_http_client(); - - let connection_string = "HostName=cool-iot-hub.azure-devices.net;SharedAccessKeyName=iot_hubowner;SharedAccessKey=YSB2ZXJ5IHNlY3VyZSBrZXkgaXMgaW1wb3J0YW50Cg=="; - let service_client = - ServiceClient::from_connection_string(http_client, connection_string, 3600)?; - - let builder = service_client.update_device_twin("deviceid"); - assert_eq!(builder.device_id, "deviceid".to_string()); - assert_eq!(builder.module_id, None); - assert_eq!(builder.method, azure_core::Method::Patch); - - Ok(()) - } - - #[test] - fn replace_device_twin_should_create_builder() -> Result<(), Box> { - use crate::service::ServiceClient; - let http_client = azure_core::new_http_client(); - - let connection_string = "HostName=cool-iot-hub.azure-devices.net;SharedAccessKeyName=iot_hubowner;SharedAccessKey=YSB2ZXJ5IHNlY3VyZSBrZXkgaXMgaW1wb3J0YW50Cg=="; - let service_client = - ServiceClient::from_connection_string(http_client, connection_string, 3600)?; - - let builder = service_client.replace_device_twin("deviceid"); - assert_eq!(builder.device_id, "deviceid".to_string()); - assert_eq!(builder.module_id, None); - assert_eq!(builder.method, azure_core::Method::Put); - - Ok(()) - } } diff --git a/sdk/iot_hub/src/service/requests/get_identity.rs b/sdk/iot_hub/src/service/requests/get_identity.rs index 38433657ba..732fc18271 100644 --- a/sdk/iot_hub/src/service/requests/get_identity.rs +++ b/sdk/iot_hub/src/service/requests/get_identity.rs @@ -1,34 +1,35 @@ use crate::service::{ServiceClient, API_VERSION}; -use azure_core::error::Error; use azure_core::Method; -use std::convert::{TryFrom, TryInto}; -/// Execute the request to get the identity of a device or module. -pub(crate) async fn get_identity( - service_client: &ServiceClient, +azure_core::operation! { + GetIdentity, + client: ServiceClient, device_id: String, - module_id: Option, -) -> azure_core::Result -where - T: TryFrom, -{ - let uri = match module_id { - Some(module_id) => format!( - "https://{}.azure-devices.net/devices/{}/modules/{}?api-version={}", - service_client.iot_hub_name, device_id, module_id, API_VERSION - ), - None => format!( - "https://{}.azure-devices.net/devices/{}?api-version={}", - service_client.iot_hub_name, device_id, API_VERSION - ), - }; + ?module_id: String +} + +impl GetIdentityBuilder { + /// Execute the request to get the identity of a device or module. + pub fn into_future(self) -> GetIdentity { + Box::pin(async move { + let uri = match self.module_id { + Some(module_id) => format!( + "https://{}.azure-devices.net/devices/{}/modules/{}?api-version={}", + self.client.iot_hub_name, self.device_id, module_id, API_VERSION + ), + None => format!( + "https://{}.azure-devices.net/devices/{}?api-version={}", + self.client.iot_hub_name, self.device_id, API_VERSION + ), + }; - let mut request = service_client.finalize_request(&uri, Method::Get)?; - request.set_body(azure_core::EMPTY_BODY); + let mut request = self.client.finalize_request(&uri, Method::Get)?; + request.set_body(azure_core::EMPTY_BODY); - service_client - .http_client() - .execute_request_check_status(&request) - .await? - .try_into() + self.client + .http_client() + .execute_request_check_status(&request) + .await + }) + } } diff --git a/sdk/iot_hub/src/service/requests/mod.rs b/sdk/iot_hub/src/service/requests/mod.rs index 0b854da245..6e0c0b18de 100644 --- a/sdk/iot_hub/src/service/requests/mod.rs +++ b/sdk/iot_hub/src/service/requests/mod.rs @@ -9,7 +9,7 @@ mod get_identity; mod get_twin; mod invoke_method; mod query; -mod update_or_replace_twin_builder; +mod update_or_replace_twin; pub use apply_on_edge_device::ApplyOnEdgeDeviceBuilder; pub use create_or_update_configuration::CreateOrUpdateConfigurationBuilder; @@ -17,9 +17,9 @@ pub use create_or_update_device_identity::CreateOrUpdateDeviceIdentityBuilder; pub use create_or_update_module_identity::CreateOrUpdateModuleIdentityBuilder; pub use delete_configuration::DeleteConfigurationBuilder; pub use delete_identity::DeleteIdentityBuilder; -pub(crate) use get_configuration::GetConfigurationBuilder; -pub(crate) use get_identity::get_identity; +pub use get_configuration::GetConfigurationBuilder; +pub use get_identity::GetIdentityBuilder; pub(crate) use get_twin::get_twin; pub use invoke_method::InvokeMethodBuilder; pub use query::QueryBuilder; -pub use update_or_replace_twin_builder::UpdateOrReplaceTwinBuilder; +pub use update_or_replace_twin::UpdateOrReplaceTwinBuilder; diff --git a/sdk/iot_hub/src/service/requests/update_or_replace_twin.rs b/sdk/iot_hub/src/service/requests/update_or_replace_twin.rs new file mode 100644 index 0000000000..011eb99fd8 --- /dev/null +++ b/sdk/iot_hub/src/service/requests/update_or_replace_twin.rs @@ -0,0 +1,108 @@ +use azure_core::headers; +use azure_core::Method; +use serde::Serialize; +use std::collections::HashMap; + +use crate::service::{ServiceClient, API_VERSION}; + +azure_core::operation! { + /// The UpdateOrReplaceTwinBuilder is used to construct a request for + /// updating or replacing a device or module twin. + UpdateOrReplaceTwin, + client: ServiceClient, + device_id: String, + method: Method, + ?module_id: String, + ?if_match: String, + ?desired_properties: serde_json::Value, + ?desired_tags: HashMap +} + +impl UpdateOrReplaceTwinBuilder { + /// Add a new tag to the desired twin. + /// + /// This function can be invoked multiple times to add multiple tags to the desired twin. + /// When adding a tag which is already in the desired twin, its value will be updated. + /// + /// # Example + /// ``` + /// # let connection_string = "HostName=cool-iot-hub.azure-devices.net;SharedAccessKeyName=iot_hubowner;SharedAccessKey=YSB2ZXJ5IHNlY3VyZSBrZXkgaXMgaW1wb3J0YW50Cg=="; + /// use azure_iot_hub::service::ServiceClient; + /// # let http_client = azure_core::new_http_client(); + /// + /// let iot_hub = ServiceClient::from_connection_string(http_client, connection_string, 3600).expect("Failed to create the ServiceClient!"); + /// let twin = iot_hub.update_device_twin("some-device") + /// .tag("TagName", "TagValue") + /// .tag("AnotherTag", "WithAnotherValue") + /// .tag("LastTag", "LastValue"); + /// ``` + pub fn tag(mut self, tag_name: T, tag_value: T) -> Self + where + T: Into, + { + let tags = self.desired_tags.get_or_insert(Default::default()); + tags.insert(tag_name.into(), tag_value.into()); + self + } + + /// Updates the twin with the desired settings + /// + /// ``` + /// use azure_iot_hub::service::ServiceClient; + /// + /// # let connection_string = "HostName=cool-iot-hub.azure-devices.net;SharedAccessKeyName=iot_hubowner;SharedAccessKey=YSB2ZXJ5IHNlY3VyZSBrZXkgaXMgaW1wb3J0YW50Cg=="; + /// # let http_client = azure_core::new_http_client(); + /// let iot_hub = ServiceClient::from_connection_string(http_client, connection_string, 3600).expect("Failed to create the ServiceClient!"); + /// let twin = iot_hub.update_device_twin("some-device") + /// .tag("TagName", "TagValue") + /// .properties(serde_json::json!({"PropertyName": "PropertyValue"})) + /// .execute(); + /// ``` + pub fn into_future(self) -> UpdateOrReplaceTwin { + Box::pin(async move { + let body = DesiredTwinBody { + tags: self.desired_tags.unwrap_or_default(), + properties: DesiredTwinProperties { + desired: self.desired_properties.unwrap_or_default(), + }, + }; + + let uri = match self.module_id { + Some(val) => format!( + "https://{}.azure-devices.net/twins/{}/modules/{}?api-version={}", + self.client.iot_hub_name, self.device_id, val, API_VERSION + ), + None => format!( + "https://{}.azure-devices.net/twins/{}?api-version={}", + self.client.iot_hub_name, self.device_id, API_VERSION + ), + }; + + let mut request = self.client.finalize_request(&uri, self.method)?; + if let Some(if_match) = self.if_match { + request.insert_header(headers::IF_MATCH, format!("\"{}\"", if_match)); + } + let body = azure_core::to_json(&body)?; + + request.set_body(body); + + self.client + .http_client() + .execute_request_check_status(&request) + .await + }) + } +} + +pub type UpdateOrReplaceTwinResponse = crate::service::CollectedResponse; + +#[derive(Serialize)] +struct DesiredTwinProperties { + desired: serde_json::Value, +} + +#[derive(Serialize)] +struct DesiredTwinBody { + tags: HashMap, + properties: DesiredTwinProperties, +} diff --git a/sdk/iot_hub/src/service/requests/update_or_replace_twin_builder.rs b/sdk/iot_hub/src/service/requests/update_or_replace_twin_builder.rs deleted file mode 100644 index a6e87a7b82..0000000000 --- a/sdk/iot_hub/src/service/requests/update_or_replace_twin_builder.rs +++ /dev/null @@ -1,175 +0,0 @@ -use azure_core::error::Error; -use azure_core::headers; -use azure_core::Method; -use serde::Serialize; -use std::collections::HashMap; -use std::convert::TryFrom; -use std::convert::TryInto; -use std::marker::PhantomData; - -use crate::service::{ServiceClient, API_VERSION}; - -/// The UpdateOrReplaceTwinBuilder is used to construct a request for -/// updating or replacing a device or module twin. -pub struct UpdateOrReplaceTwinBuilder<'a, R> -where - R: TryFrom, -{ - service_client: &'a ServiceClient, - pub(crate) device_id: String, - pub(crate) module_id: Option, - if_match: Option, - desired_properties: Option, - desired_tags: HashMap, - pub(crate) method: Method, - desired_twin_return_type: PhantomData, -} - -impl<'a, R> UpdateOrReplaceTwinBuilder<'a, R> -where - R: TryFrom, -{ - pub(crate) fn new( - service_client: &'a ServiceClient, - device_id: String, - module_id: Option, - method: Method, - ) -> Self { - Self { - service_client, - device_id, - module_id, - if_match: None, - desired_properties: None, - desired_tags: HashMap::new(), - method, - desired_twin_return_type: PhantomData, - } - } - - /// Add a new tag to the desired twin. - /// - /// This function can be invoked multiple times to add multiple tags to the desired twin. - /// When adding a tag which is already in the desired twin, its value will be updated. - /// - /// # Example - /// ``` - /// # let connection_string = "HostName=cool-iot-hub.azure-devices.net;SharedAccessKeyName=iot_hubowner;SharedAccessKey=YSB2ZXJ5IHNlY3VyZSBrZXkgaXMgaW1wb3J0YW50Cg=="; - /// use azure_iot_hub::service::ServiceClient; - /// # let http_client = azure_core::new_http_client(); - /// - /// let iot_hub = ServiceClient::from_connection_string(http_client, connection_string, 3600).expect("Failed to create the ServiceClient!"); - /// let twin = iot_hub.update_device_twin("some-device") - /// .tag("TagName", "TagValue") - /// .tag("AnotherTag", "WithAnotherValue") - /// .tag("LastTag", "LastValue"); - /// ``` - pub fn tag(mut self, tag_name: T, tag_value: T) -> Self - where - T: Into, - { - self.desired_tags.insert(tag_name.into(), tag_value.into()); - self - } - - /// Add new properties to the desired twin - /// - /// # Example - /// ``` - /// use azure_iot_hub::service::ServiceClient; - /// # let http_client = azure_core::new_http_client(); - /// - /// # let connection_string = "HostName=cool-iot-hub.azure-devices.net;SharedAccessKeyName=iot_hubowner;SharedAccessKey=YSB2ZXJ5IHNlY3VyZSBrZXkgaXMgaW1wb3J0YW50Cg=="; - /// let iot_hub = ServiceClient::from_connection_string(http_client, connection_string, 3600).expect("Failed to create the ServiceClient!"); - /// let twin = iot_hub.update_device_twin("some-device") - /// .properties(serde_json::json!({ - /// "PropertyName": "PropertyValue", - /// "ParentProperty": { - /// "ChildProperty": "ChildValue" - /// } - /// })); - pub fn properties(mut self, desired_properties: serde_json::Value) -> Self { - self.desired_properties = Some(desired_properties); - self - } - - /// Set the ETag for the twin - /// - /// ``` - /// use azure_iot_hub::service::ServiceClient; - /// - /// # let connection_string = "HostName=cool-iot-hub.azure-devices.net;SharedAccessKeyName=iot_hubowner;SharedAccessKey=YSB2ZXJ5IHNlY3VyZSBrZXkgaXMgaW1wb3J0YW50Cg=="; - /// # let http_client = azure_core::new_http_client(); - /// - /// let iot_hub = ServiceClient::from_connection_string(http_client, connection_string, 3600).expect("Failed to create the ServiceClient!"); - /// let twin = iot_hub.update_device_twin("some-device") - /// .if_match("AAAAAAAAAAA="); - /// ``` - pub fn if_match(mut self, if_match: T) -> Self - where - T: Into, - { - self.if_match = Some(if_match.into()); - self - } - - /// Updates the twin with the desired settings - /// - /// ``` - /// use azure_iot_hub::service::ServiceClient; - /// - /// # let connection_string = "HostName=cool-iot-hub.azure-devices.net;SharedAccessKeyName=iot_hubowner;SharedAccessKey=YSB2ZXJ5IHNlY3VyZSBrZXkgaXMgaW1wb3J0YW50Cg=="; - /// # let http_client = azure_core::new_http_client(); - /// let iot_hub = ServiceClient::from_connection_string(http_client, connection_string, 3600).expect("Failed to create the ServiceClient!"); - /// let twin = iot_hub.update_device_twin("some-device") - /// .tag("TagName", "TagValue") - /// .properties(serde_json::json!({"PropertyName": "PropertyValue"})) - /// .execute(); - /// ``` - pub async fn execute(self) -> azure_core::Result { - let body = DesiredTwinBody { - tags: self.desired_tags, - properties: DesiredTwinProperties { - desired: self - .desired_properties - .unwrap_or_else(|| serde_json::json!({})), - }, - }; - - let uri = match self.module_id { - Some(val) => format!( - "https://{}.azure-devices.net/twins/{}/modules/{}?api-version={}", - self.service_client.iot_hub_name, self.device_id, val, API_VERSION - ), - None => format!( - "https://{}.azure-devices.net/twins/{}?api-version={}", - self.service_client.iot_hub_name, self.device_id, API_VERSION - ), - }; - - let mut request = self.service_client.finalize_request(&uri, self.method)?; - if let Some(if_match) = self.if_match { - request.insert_header(headers::IF_MATCH, format!("\"{}\"", if_match)); - } - let body = azure_core::to_json(&body)?; - - request.set_body(body); - - self.service_client - .http_client() - .execute_request_check_status(&request) - .await? - .try_into() - } -} - -#[derive(Serialize)] -struct DesiredTwinProperties { - desired: serde_json::Value, -} - -#[derive(Serialize)] -struct DesiredTwinBody { - tags: HashMap, - properties: DesiredTwinProperties, -} From 14f777f997e65906ac5c431b5e65119fa9625777 Mon Sep 17 00:00:00 2001 From: Ryan Levick Date: Wed, 27 Jul 2022 14:05:37 +0200 Subject: [PATCH 10/14] GetTwin --- sdk/iot_hub/src/service/mod.rs | 19 +++--- .../src/service/requests/get_configuration.rs | 1 + .../src/service/requests/get_identity.rs | 4 ++ sdk/iot_hub/src/service/requests/get_twin.rs | 59 ++++++++++--------- sdk/iot_hub/src/service/requests/mod.rs | 2 +- 5 files changed, 44 insertions(+), 41 deletions(-) diff --git a/sdk/iot_hub/src/service/mod.rs b/sdk/iot_hub/src/service/mod.rs index a24328e43d..322224898a 100644 --- a/sdk/iot_hub/src/service/mod.rs +++ b/sdk/iot_hub/src/service/mod.rs @@ -14,13 +14,12 @@ pub mod resources; pub mod responses; use crate::service::requests::{ - get_twin, ApplyOnEdgeDeviceBuilder, CreateOrUpdateConfigurationBuilder, + ApplyOnEdgeDeviceBuilder, CreateOrUpdateConfigurationBuilder, CreateOrUpdateDeviceIdentityBuilder, CreateOrUpdateModuleIdentityBuilder, - DeleteConfigurationBuilder, DeleteIdentityBuilder, GetIdentityBuilder, InvokeMethodBuilder, - QueryBuilder, UpdateOrReplaceTwinBuilder, + DeleteConfigurationBuilder, DeleteIdentityBuilder, GetIdentityBuilder, GetTwinBuilder, + InvokeMethodBuilder, QueryBuilder, UpdateOrReplaceTwinBuilder, }; use crate::service::resources::identity::IdentityOperation; -use crate::service::responses::{DeviceTwinResponse, ModuleTwinResponse}; use self::requests::GetConfigurationBuilder; use self::resources::{AuthenticationMechanism, Status}; @@ -328,16 +327,12 @@ impl ServiceClient { /// let iot_hub = ServiceClient::from_connection_string(http_client, connection_string, 3600).expect("Failed to create the ServiceClient!"); /// let twin = iot_hub.get_module_twin("some-device", "some-module"); /// ``` - pub async fn get_module_twin( - &self, - device_id: S, - module_id: T, - ) -> azure_core::Result + pub async fn get_module_twin(&self, device_id: S, module_id: T) -> GetTwinBuilder where S: Into, T: Into, { - get_twin(self, device_id.into(), Some(module_id.into())).await + GetTwinBuilder::new(self.clone(), device_id.into()).module_id(module_id) } /// Get the HttpClient of the IoTHub service @@ -356,11 +351,11 @@ impl ServiceClient { /// let iot_hub = ServiceClient::from_connection_string(http_client, connection_string, 3600).expect("Failed to create the ServiceClient!"); /// let twin = iot_hub.get_device_twin("some-device"); /// ``` - pub async fn get_device_twin(&self, device_id: S) -> azure_core::Result + pub async fn get_device_twin(&self, device_id: S) -> GetTwinBuilder where S: Into, { - get_twin(self, device_id.into(), None).await + GetTwinBuilder::new(self.clone(), device_id.into()) } /// Update the module twin of a given device or module diff --git a/sdk/iot_hub/src/service/requests/get_configuration.rs b/sdk/iot_hub/src/service/requests/get_configuration.rs index 96a7ed9bef..139e57d53f 100644 --- a/sdk/iot_hub/src/service/requests/get_configuration.rs +++ b/sdk/iot_hub/src/service/requests/get_configuration.rs @@ -2,6 +2,7 @@ use crate::service::{ServiceClient, API_VERSION}; use azure_core::Method; azure_core::operation! { + /// The GetConfigurationBuilder is used to get configuration GetConfiguration, client: ServiceClient, ?configuration_id: String diff --git a/sdk/iot_hub/src/service/requests/get_identity.rs b/sdk/iot_hub/src/service/requests/get_identity.rs index 732fc18271..fcc98f02f9 100644 --- a/sdk/iot_hub/src/service/requests/get_identity.rs +++ b/sdk/iot_hub/src/service/requests/get_identity.rs @@ -2,6 +2,8 @@ use crate::service::{ServiceClient, API_VERSION}; use azure_core::Method; azure_core::operation! { + + /// The GetIdentityBuilder is used to construct a request to get identity GetIdentity, client: ServiceClient, device_id: String, @@ -33,3 +35,5 @@ impl GetIdentityBuilder { }) } } + +pub type GetIdentityResponse = crate::service::CollectedResponse; diff --git a/sdk/iot_hub/src/service/requests/get_twin.rs b/sdk/iot_hub/src/service/requests/get_twin.rs index 4aca9519d0..8389ebb058 100644 --- a/sdk/iot_hub/src/service/requests/get_twin.rs +++ b/sdk/iot_hub/src/service/requests/get_twin.rs @@ -1,35 +1,38 @@ use crate::service::{ServiceClient, API_VERSION}; -use azure_core::error::Error; use azure_core::Method; -use std::convert::TryFrom; -use std::convert::TryInto; -/// Execute the request to get the twin of a module or device. -pub(crate) async fn get_twin( - service_client: &ServiceClient, +azure_core::operation! { + /// The GetTwinBuilder is used to construct a request to get a twin module or device + GetTwin, + client: ServiceClient, device_id: String, - module_id: Option, -) -> azure_core::Result -where - T: TryFrom, -{ - let uri = match module_id { - Some(val) => format!( - "https://{}.azure-devices.net/twins/{}/modules/{}?api-version={}", - service_client.iot_hub_name, device_id, val, API_VERSION - ), - None => format!( - "https://{}.azure-devices.net/twins/{}?api-version={}", - service_client.iot_hub_name, device_id, API_VERSION - ), - }; + ?module_id: String +} + +impl GetTwinBuilder { + /// Execute the request to get the twin of a module or device. + pub fn into_future(self) -> GetTwin { + Box::pin(async move { + let uri = match self.module_id { + Some(val) => format!( + "https://{}.azure-devices.net/twins/{}/modules/{}?api-version={}", + self.client.iot_hub_name, self.device_id, val, API_VERSION + ), + None => format!( + "https://{}.azure-devices.net/twins/{}?api-version={}", + self.client.iot_hub_name, self.device_id, API_VERSION + ), + }; - let mut request = service_client.finalize_request(&uri, Method::Get)?; - request.set_body(azure_core::EMPTY_BODY); + let mut request = self.client.finalize_request(&uri, Method::Get)?; + request.set_body(azure_core::EMPTY_BODY); - service_client - .http_client() - .execute_request_check_status(&request) - .await? - .try_into() + self.client + .http_client() + .execute_request_check_status(&request) + .await + }) + } } + +pub type GetTwinResponse = crate::service::CollectedResponse; diff --git a/sdk/iot_hub/src/service/requests/mod.rs b/sdk/iot_hub/src/service/requests/mod.rs index 6e0c0b18de..195f8c4860 100644 --- a/sdk/iot_hub/src/service/requests/mod.rs +++ b/sdk/iot_hub/src/service/requests/mod.rs @@ -19,7 +19,7 @@ pub use delete_configuration::DeleteConfigurationBuilder; pub use delete_identity::DeleteIdentityBuilder; pub use get_configuration::GetConfigurationBuilder; pub use get_identity::GetIdentityBuilder; -pub(crate) use get_twin::get_twin; +pub use get_twin::GetTwinBuilder; pub use invoke_method::InvokeMethodBuilder; pub use query::QueryBuilder; pub use update_or_replace_twin::UpdateOrReplaceTwinBuilder; From 9d4a8741f416823dab599899a57481b88549e9f4 Mon Sep 17 00:00:00 2001 From: Ryan Levick Date: Wed, 27 Jul 2022 14:58:33 +0200 Subject: [PATCH 11/14] Fix examples --- .../apply_configuration_on_edge_device.rs | 2 +- sdk/iot_hub/examples/configuration.rs | 16 ++++--- sdk/iot_hub/examples/device_identity.rs | 20 +++++--- sdk/iot_hub/examples/directmethod.rs | 14 ++++-- sdk/iot_hub/examples/gettwin.rs | 5 +- sdk/iot_hub/examples/module_identity.rs | 14 ++++-- sdk/iot_hub/examples/query_iothub.rs | 8 ++-- sdk/iot_hub/examples/updatetwin.rs | 4 +- sdk/iot_hub/src/service/mod.rs | 4 +- .../create_or_update_configuration.rs | 46 +++++++++++++++++++ .../src/service/requests/get_identity.rs | 3 +- .../src/service/requests/invoke_method.rs | 2 +- 12 files changed, 102 insertions(+), 36 deletions(-) diff --git a/sdk/iot_hub/examples/apply_configuration_on_edge_device.rs b/sdk/iot_hub/examples/apply_configuration_on_edge_device.rs index 8a95fbed3f..40dfa03fa6 100644 --- a/sdk/iot_hub/examples/apply_configuration_on_edge_device.rs +++ b/sdk/iot_hub/examples/apply_configuration_on_edge_device.rs @@ -62,7 +62,7 @@ async fn main() -> Result<(), Box> { service_client .apply_on_edge_device(device_id) .modules_content(modules_content) - .execute() + .into_future() .await?; println!("Successfully applied the configuration"); diff --git a/sdk/iot_hub/examples/configuration.rs b/sdk/iot_hub/examples/configuration.rs index ae05941759..8718c633de 100644 --- a/sdk/iot_hub/examples/configuration.rs +++ b/sdk/iot_hub/examples/configuration.rs @@ -1,4 +1,4 @@ -use azure_iot_hub::service::ServiceClient; +use azure_iot_hub::service::{resources::Configuration, ServiceClient}; use std::error::Error; #[tokio::main] @@ -29,7 +29,7 @@ async fn main() -> Result<(), Box> { "metric1", "SELECT deviceId FROM devices WHERE properties.reported.lastDesiredStatus.code = 200", ) - .execute() + .into_future() .await?; println!( @@ -38,7 +38,11 @@ async fn main() -> Result<(), Box> { ); println!("Getting configuration: {}", configuration_id); - let configuration = service_client.get_configuration(configuration_id).await?; + let configuration = service_client + .get_configuration(configuration_id) + .into_future() + .await?; + let configuration: Configuration = configuration.try_into()?; println!( "Successfully retrieved the new configuration '{:?}'", @@ -65,10 +69,10 @@ async fn main() -> Result<(), Box> { })) .labels(configuration.labels) .metrics(configuration.metrics.queries) - .execute() + .into_future() .await?; - let multiple_configurations = service_client.get_configurations().await?; + let multiple_configurations = service_client.get_configurations().into_future().await?; println!( "Successfully retrieved all configurations '{:?}'", multiple_configurations @@ -86,7 +90,7 @@ async fn main() -> Result<(), Box> { service_client .delete_configuration(&configuration.id, configuration.etag) - .execute() + .into_future() .await?; println!( diff --git a/sdk/iot_hub/examples/device_identity.rs b/sdk/iot_hub/examples/device_identity.rs index d32f2c728f..194eb4b083 100644 --- a/sdk/iot_hub/examples/device_identity.rs +++ b/sdk/iot_hub/examples/device_identity.rs @@ -1,4 +1,5 @@ use azure_iot_hub::service::resources::{AuthenticationMechanism, DesiredCapability, Status}; +use azure_iot_hub::service::responses::DeviceIdentityResponse; use azure_iot_hub::service::ServiceClient; use std::error::Error; @@ -16,8 +17,7 @@ async fn main() -> Result<(), Box> { let service_client = ServiceClient::from_connection_string(http_client, iot_hub_connection_string, 3600)?; let device = service_client - .create_device_identity() - .execute( + .create_device_identity( &device_id, Status::Enabled, AuthenticationMechanism::new_using_symmetric_key( @@ -25,6 +25,7 @@ async fn main() -> Result<(), Box> { "6YS6w5wqkpdfkEW7iOP1NvituehFlFRfPko2n7KY4Gk", ), ) + .into_future() .await?; println!("Successfully created a new device '{}'", device.device_id); @@ -34,26 +35,31 @@ async fn main() -> Result<(), Box> { device.device_id ); let device = service_client - .update_device_identity(device.etag) - .device_capability(DesiredCapability::IotEdge) - .execute( + .update_device_identity( &device_id, Status::Enabled, AuthenticationMechanism::new_using_symmetric_key( "QhgevIUBSWe37q1MP+M/vtktjOcrE74BVbpcxlLQw58=", "6YS6w5wqkpdfkEW7iOP1NvituehFlFRfPko2n7KY4Gk", ), + device.etag, ) + .device_capability(DesiredCapability::IotEdge) + .into_future() .await?; println!("Getting device identity of '{}'", device.device_id); - let device = service_client.get_device_identity(device.device_id).await?; + let device = service_client + .get_device_identity(device.device_id) + .into_future() + .await?; + let device: DeviceIdentityResponse = device.try_into()?; println!("Identity is: {:?}", device); println!("Deleting device '{}'", device.device_id); service_client .delete_device_identity(device.device_id, device.etag) - .execute() + .into_future() .await?; Ok(()) diff --git a/sdk/iot_hub/examples/directmethod.rs b/sdk/iot_hub/examples/directmethod.rs index 088508f9e0..a1f8f55f4d 100644 --- a/sdk/iot_hub/examples/directmethod.rs +++ b/sdk/iot_hub/examples/directmethod.rs @@ -31,12 +31,16 @@ async fn main() -> Result<(), Box> { method_name, device_id, module_id, service_client.iot_hub_name ); - let direct_method = - service_client.create_module_method(device_id, module_id, method_name, 30, 30); + let direct_method = service_client.create_module_method( + serde_json::from_str(&payload)?, + device_id, + module_id, + method_name, + 30, + 30, + ); - let response = direct_method - .execute(serde_json::from_str(&payload)?) - .await?; + let response = direct_method.into_future().await?; println!( "Received a response from the direct method with status code {} and payload {:?}", diff --git a/sdk/iot_hub/examples/gettwin.rs b/sdk/iot_hub/examples/gettwin.rs index 44b2770bab..59dc56f94c 100644 --- a/sdk/iot_hub/examples/gettwin.rs +++ b/sdk/iot_hub/examples/gettwin.rs @@ -15,7 +15,10 @@ async fn main() -> Result<(), Box> { let http_client = azure_core::new_http_client(); let service_client = ServiceClient::from_connection_string(http_client, iot_hub_connection_string, 3600)?; - let twin = service_client.get_device_twin(device_id).await?; + let twin = service_client + .get_device_twin(device_id) + .into_future() + .await?; println!("Received device twin: {:?}", twin); diff --git a/sdk/iot_hub/examples/module_identity.rs b/sdk/iot_hub/examples/module_identity.rs index b1983124e8..f070a05b92 100644 --- a/sdk/iot_hub/examples/module_identity.rs +++ b/sdk/iot_hub/examples/module_identity.rs @@ -1,4 +1,5 @@ use azure_iot_hub::service::resources::AuthenticationMechanism; +use azure_iot_hub::service::responses::ModuleIdentityResponse; use azure_iot_hub::service::ServiceClient; use std::error::Error; @@ -19,8 +20,7 @@ async fn main() -> Result<(), Box> { let service_client = ServiceClient::from_connection_string(http_client, iot_hub_connection_string, 3600)?; let module = service_client - .create_module_identity() - .execute( + .create_module_identity( &device_id, &module_id, "IoTEdge", @@ -29,6 +29,7 @@ async fn main() -> Result<(), Box> { "6YS6w5wqkpdfkEW7iOP1NvituehFlFRfPko2n7KY4Gk", ), ) + .into_future() .await?; println!( @@ -41,16 +42,17 @@ async fn main() -> Result<(), Box> { module.device_id, module.module_id ); let module = service_client - .update_module_identity(module.etag) - .execute( + .update_module_identity( &device_id, &module_id, "Docker", + module.etag, AuthenticationMechanism::new_using_symmetric_key( "QhgevIUBSWe37q1MP+M/vtktjOcrE74BVbpcxlLQw58=", "6YS6w5wqkpdfkEW7iOP1NvituehFlFRfPko2n7KY4Gk", ), ) + .into_future() .await?; println!( @@ -59,7 +61,9 @@ async fn main() -> Result<(), Box> { ); let module = service_client .get_module_identity(module.device_id, module.module_id) + .into_future() .await?; + let module: ModuleIdentityResponse = module.try_into()?; println!("Identity is: {:?}", module); println!( @@ -68,7 +72,7 @@ async fn main() -> Result<(), Box> { ); service_client .delete_module_identity(module.device_id, module.module_id, module.etag) - .execute() + .into_future() .await?; Ok(()) diff --git a/sdk/iot_hub/examples/query_iothub.rs b/sdk/iot_hub/examples/query_iothub.rs index 64bb04f6fd..3cf75b771b 100644 --- a/sdk/iot_hub/examples/query_iothub.rs +++ b/sdk/iot_hub/examples/query_iothub.rs @@ -16,9 +16,9 @@ async fn main() -> Result<(), Box> { ServiceClient::from_connection_string(http_client, iot_hub_connection_string, 3600)?; let response = service_client - .query() + .query(query) .max_item_count(1) - .execute(query) + .into_future() .await?; println!( @@ -32,10 +32,10 @@ async fn main() -> Result<(), Box> { }; let response = service_client - .query() + .query(query) .max_item_count(1) .continuation(token) - .execute(query) + .into_future() .await?; println!( diff --git a/sdk/iot_hub/examples/updatetwin.rs b/sdk/iot_hub/examples/updatetwin.rs index df28b74ad8..bdf2ebc006 100644 --- a/sdk/iot_hub/examples/updatetwin.rs +++ b/sdk/iot_hub/examples/updatetwin.rs @@ -22,8 +22,8 @@ async fn main() -> Result<(), Box> { ServiceClient::from_connection_string(http_client, iot_hub_connection_string, 3600)?; let updated_twin = service_client .update_device_twin(device_id) - .properties(serde_json::from_str(&payload)?) - .execute() + .desired_properties(serde_json::from_str(&payload)?) + .into_future() .await?; println!("Received device twin: {:?}", updated_twin); diff --git a/sdk/iot_hub/src/service/mod.rs b/sdk/iot_hub/src/service/mod.rs index 322224898a..480569465a 100644 --- a/sdk/iot_hub/src/service/mod.rs +++ b/sdk/iot_hub/src/service/mod.rs @@ -327,7 +327,7 @@ impl ServiceClient { /// let iot_hub = ServiceClient::from_connection_string(http_client, connection_string, 3600).expect("Failed to create the ServiceClient!"); /// let twin = iot_hub.get_module_twin("some-device", "some-module"); /// ``` - pub async fn get_module_twin(&self, device_id: S, module_id: T) -> GetTwinBuilder + pub fn get_module_twin(&self, device_id: S, module_id: T) -> GetTwinBuilder where S: Into, T: Into, @@ -351,7 +351,7 @@ impl ServiceClient { /// let iot_hub = ServiceClient::from_connection_string(http_client, connection_string, 3600).expect("Failed to create the ServiceClient!"); /// let twin = iot_hub.get_device_twin("some-device"); /// ``` - pub async fn get_device_twin(&self, device_id: S) -> GetTwinBuilder + pub fn get_device_twin(&self, device_id: S) -> GetTwinBuilder where S: Into, { diff --git a/sdk/iot_hub/src/service/requests/create_or_update_configuration.rs b/sdk/iot_hub/src/service/requests/create_or_update_configuration.rs index 9e416acaec..0a039f584d 100644 --- a/sdk/iot_hub/src/service/requests/create_or_update_configuration.rs +++ b/sdk/iot_hub/src/service/requests/create_or_update_configuration.rs @@ -23,6 +23,52 @@ azure_core::operation! { } impl CreateOrUpdateConfigurationBuilder { + /// Sets the device content for the configuration + /// The content cannot be updated once it has been created. + pub fn device_content(mut self, device_content: serde_json::Value) -> Self { + let content = self.content.get_or_insert(Default::default()); + content.device_content = Some(device_content); + self + } + + /// Sets the module content for the configuration. + /// The content cannot be updated once it has been created. + pub fn module_content(mut self, module_content: serde_json::Value) -> Self { + let content = self.content.get_or_insert(Default::default()); + content.module_content = Some(module_content); + self + } + + /// Sets the module content for the configuration + /// The content cannot be updated once it has been created. + pub fn modules_content(mut self, modules_content: serde_json::Value) -> Self { + let content = self.content.get_or_insert(Default::default()); + content.modules_content = Some(modules_content); + self + } + + /// Add a metric to the configuration + pub fn metric(mut self, key: S, value: T) -> Self + where + S: Into, + T: Into, + { + let metrics = self.metrics.get_or_insert(Default::default()); + metrics.insert(key.into(), value.into()); + self + } + + /// Add a label to the configuration. + pub fn label(mut self, key: S, value: T) -> Self + where + S: Into, + T: Into, + { + let labels = self.labels.get_or_insert(Default::default()); + labels.insert(key.into(), value.into()); + self + } + /// Performs the create or update request on the device identity pub fn into_future(self) -> CreateOrUpdateConfiguration { Box::pin(async move { diff --git a/sdk/iot_hub/src/service/requests/get_identity.rs b/sdk/iot_hub/src/service/requests/get_identity.rs index fcc98f02f9..8ab6d1207e 100644 --- a/sdk/iot_hub/src/service/requests/get_identity.rs +++ b/sdk/iot_hub/src/service/requests/get_identity.rs @@ -2,7 +2,6 @@ use crate::service::{ServiceClient, API_VERSION}; use azure_core::Method; azure_core::operation! { - /// The GetIdentityBuilder is used to construct a request to get identity GetIdentity, client: ServiceClient, @@ -12,7 +11,7 @@ azure_core::operation! { impl GetIdentityBuilder { /// Execute the request to get the identity of a device or module. - pub fn into_future(self) -> GetIdentity { + pub fn into_future(self) -> GetIdentity { Box::pin(async move { let uri = match self.module_id { Some(module_id) => format!( diff --git a/sdk/iot_hub/src/service/requests/invoke_method.rs b/sdk/iot_hub/src/service/requests/invoke_method.rs index 9093b671b3..38a4d72573 100644 --- a/sdk/iot_hub/src/service/requests/invoke_method.rs +++ b/sdk/iot_hub/src/service/requests/invoke_method.rs @@ -42,7 +42,7 @@ impl InvokeMethodBuilder { /// /// great_method.execute(serde_json::json!({"hello": "world"})); /// ``` - pub async fn into_future(self) -> InvokeMethod { + pub fn into_future(self) -> InvokeMethod { Box::pin(async move { let uri = match &self.module_id { Some(module_id_value) => format!( From 8348515f5371daefb3c7eb062a28b8ddcb1283df Mon Sep 17 00:00:00 2001 From: Ryan Levick Date: Wed, 27 Jul 2022 16:22:43 +0200 Subject: [PATCH 12/14] Fix clippy errors --- .../src/service/requests/create_or_update_module_identity.rs | 2 +- sdk/iot_hub/src/service/requests/query.rs | 4 +--- 2 files changed, 2 insertions(+), 4 deletions(-) diff --git a/sdk/iot_hub/src/service/requests/create_or_update_module_identity.rs b/sdk/iot_hub/src/service/requests/create_or_update_module_identity.rs index 038a887997..3d98496426 100644 --- a/sdk/iot_hub/src/service/requests/create_or_update_module_identity.rs +++ b/sdk/iot_hub/src/service/requests/create_or_update_module_identity.rs @@ -20,7 +20,7 @@ azure_core::operation! { etag: Option, } -impl<'a> CreateOrUpdateModuleIdentityBuilder { +impl CreateOrUpdateModuleIdentityBuilder { /// Performs the create or update request on the device identity pub fn into_future(self) -> CreateOrUpdateModuleIdentity { Box::pin(async move { diff --git a/sdk/iot_hub/src/service/requests/query.rs b/sdk/iot_hub/src/service/requests/query.rs index b2f2cb1c37..577c11a69d 100644 --- a/sdk/iot_hub/src/service/requests/query.rs +++ b/sdk/iot_hub/src/service/requests/query.rs @@ -41,9 +41,7 @@ impl QueryBuilder { self.client.iot_hub_name, API_VERSION ); - let query_body = QueryBody { - query: self.query.into(), - }; + let query_body = QueryBody { query: self.query }; let body = azure_core::to_json(&query_body)?; let mut request = self.client.finalize_request(&uri, Method::Post)?; From 896c9d96ef8c9ee1cdafd7a2fea1a487c58c80d7 Mon Sep 17 00:00:00 2001 From: Ryan Levick Date: Thu, 28 Jul 2022 12:21:05 +0200 Subject: [PATCH 13/14] Rename module --- sdk/iot_hub/src/service/mod.rs | 16 ++++++++-------- .../apply_on_edge_device.rs | 0 .../create_or_update_configuration.rs | 0 .../create_or_update_device_identity.rs | 0 .../create_or_update_module_identity.rs | 0 .../delete_configuration.rs | 0 .../{requests => operations}/delete_identity.rs | 0 .../get_configuration.rs | 0 .../{requests => operations}/get_identity.rs | 0 .../service/{requests => operations}/get_twin.rs | 0 .../{requests => operations}/invoke_method.rs | 0 .../src/service/{requests => operations}/mod.rs | 0 .../service/{requests => operations}/query.rs | 0 .../update_or_replace_twin.rs | 0 14 files changed, 8 insertions(+), 8 deletions(-) rename sdk/iot_hub/src/service/{requests => operations}/apply_on_edge_device.rs (100%) rename sdk/iot_hub/src/service/{requests => operations}/create_or_update_configuration.rs (100%) rename sdk/iot_hub/src/service/{requests => operations}/create_or_update_device_identity.rs (100%) rename sdk/iot_hub/src/service/{requests => operations}/create_or_update_module_identity.rs (100%) rename sdk/iot_hub/src/service/{requests => operations}/delete_configuration.rs (100%) rename sdk/iot_hub/src/service/{requests => operations}/delete_identity.rs (100%) rename sdk/iot_hub/src/service/{requests => operations}/get_configuration.rs (100%) rename sdk/iot_hub/src/service/{requests => operations}/get_identity.rs (100%) rename sdk/iot_hub/src/service/{requests => operations}/get_twin.rs (100%) rename sdk/iot_hub/src/service/{requests => operations}/invoke_method.rs (100%) rename sdk/iot_hub/src/service/{requests => operations}/mod.rs (100%) rename sdk/iot_hub/src/service/{requests => operations}/query.rs (100%) rename sdk/iot_hub/src/service/{requests => operations}/update_or_replace_twin.rs (100%) diff --git a/sdk/iot_hub/src/service/mod.rs b/sdk/iot_hub/src/service/mod.rs index 480569465a..5b5a4d887b 100644 --- a/sdk/iot_hub/src/service/mod.rs +++ b/sdk/iot_hub/src/service/mod.rs @@ -6,14 +6,14 @@ use hmac::{Hmac, Mac}; use sha2::Sha256; use std::sync::Arc; -/// The requests module contains any request that the IoT Hub service client can perform. -pub mod requests; -/// The resources module contains various types that some of the requests or responses use. +/// Contains any operation that the IoT Hub service client can perform. +pub mod operations; +/// Contains various types that some of the requests or responses use. pub mod resources; -/// The response module contains responses for the requests that the IoT Hub service client can perform. +/// Contains responses for the requests that the IoT Hub service client can perform. pub mod responses; -use crate::service::requests::{ +use crate::service::operations::{ ApplyOnEdgeDeviceBuilder, CreateOrUpdateConfigurationBuilder, CreateOrUpdateDeviceIdentityBuilder, CreateOrUpdateModuleIdentityBuilder, DeleteConfigurationBuilder, DeleteIdentityBuilder, GetIdentityBuilder, GetTwinBuilder, @@ -21,7 +21,7 @@ use crate::service::requests::{ }; use crate::service::resources::identity::IdentityOperation; -use self::requests::GetConfigurationBuilder; +use self::operations::GetConfigurationBuilder; use self::resources::{AuthenticationMechanism, Status}; /// The API version to use for any requests @@ -264,7 +264,7 @@ impl ServiceClient { method_name: T, response_time_out: u64, connect_time_out: u64, - ) -> requests::InvokeMethodBuilder + ) -> operations::InvokeMethodBuilder where S: Into, T: Into, @@ -299,7 +299,7 @@ impl ServiceClient { method_name: U, response_time_out: u64, connect_time_out: u64, - ) -> requests::InvokeMethodBuilder + ) -> operations::InvokeMethodBuilder where S: Into, T: Into, diff --git a/sdk/iot_hub/src/service/requests/apply_on_edge_device.rs b/sdk/iot_hub/src/service/operations/apply_on_edge_device.rs similarity index 100% rename from sdk/iot_hub/src/service/requests/apply_on_edge_device.rs rename to sdk/iot_hub/src/service/operations/apply_on_edge_device.rs diff --git a/sdk/iot_hub/src/service/requests/create_or_update_configuration.rs b/sdk/iot_hub/src/service/operations/create_or_update_configuration.rs similarity index 100% rename from sdk/iot_hub/src/service/requests/create_or_update_configuration.rs rename to sdk/iot_hub/src/service/operations/create_or_update_configuration.rs diff --git a/sdk/iot_hub/src/service/requests/create_or_update_device_identity.rs b/sdk/iot_hub/src/service/operations/create_or_update_device_identity.rs similarity index 100% rename from sdk/iot_hub/src/service/requests/create_or_update_device_identity.rs rename to sdk/iot_hub/src/service/operations/create_or_update_device_identity.rs diff --git a/sdk/iot_hub/src/service/requests/create_or_update_module_identity.rs b/sdk/iot_hub/src/service/operations/create_or_update_module_identity.rs similarity index 100% rename from sdk/iot_hub/src/service/requests/create_or_update_module_identity.rs rename to sdk/iot_hub/src/service/operations/create_or_update_module_identity.rs diff --git a/sdk/iot_hub/src/service/requests/delete_configuration.rs b/sdk/iot_hub/src/service/operations/delete_configuration.rs similarity index 100% rename from sdk/iot_hub/src/service/requests/delete_configuration.rs rename to sdk/iot_hub/src/service/operations/delete_configuration.rs diff --git a/sdk/iot_hub/src/service/requests/delete_identity.rs b/sdk/iot_hub/src/service/operations/delete_identity.rs similarity index 100% rename from sdk/iot_hub/src/service/requests/delete_identity.rs rename to sdk/iot_hub/src/service/operations/delete_identity.rs diff --git a/sdk/iot_hub/src/service/requests/get_configuration.rs b/sdk/iot_hub/src/service/operations/get_configuration.rs similarity index 100% rename from sdk/iot_hub/src/service/requests/get_configuration.rs rename to sdk/iot_hub/src/service/operations/get_configuration.rs diff --git a/sdk/iot_hub/src/service/requests/get_identity.rs b/sdk/iot_hub/src/service/operations/get_identity.rs similarity index 100% rename from sdk/iot_hub/src/service/requests/get_identity.rs rename to sdk/iot_hub/src/service/operations/get_identity.rs diff --git a/sdk/iot_hub/src/service/requests/get_twin.rs b/sdk/iot_hub/src/service/operations/get_twin.rs similarity index 100% rename from sdk/iot_hub/src/service/requests/get_twin.rs rename to sdk/iot_hub/src/service/operations/get_twin.rs diff --git a/sdk/iot_hub/src/service/requests/invoke_method.rs b/sdk/iot_hub/src/service/operations/invoke_method.rs similarity index 100% rename from sdk/iot_hub/src/service/requests/invoke_method.rs rename to sdk/iot_hub/src/service/operations/invoke_method.rs diff --git a/sdk/iot_hub/src/service/requests/mod.rs b/sdk/iot_hub/src/service/operations/mod.rs similarity index 100% rename from sdk/iot_hub/src/service/requests/mod.rs rename to sdk/iot_hub/src/service/operations/mod.rs diff --git a/sdk/iot_hub/src/service/requests/query.rs b/sdk/iot_hub/src/service/operations/query.rs similarity index 100% rename from sdk/iot_hub/src/service/requests/query.rs rename to sdk/iot_hub/src/service/operations/query.rs diff --git a/sdk/iot_hub/src/service/requests/update_or_replace_twin.rs b/sdk/iot_hub/src/service/operations/update_or_replace_twin.rs similarity index 100% rename from sdk/iot_hub/src/service/requests/update_or_replace_twin.rs rename to sdk/iot_hub/src/service/operations/update_or_replace_twin.rs From 4322bf9b84e7a7f1796a7ea55e27e3d1ad5c0bdc Mon Sep 17 00:00:00 2001 From: Ryan Levick Date: Thu, 28 Jul 2022 12:43:40 +0200 Subject: [PATCH 14/14] Fix doc tests --- sdk/iot_hub/examples/directmethod.rs | 4 +- sdk/iot_hub/examples/module_identity.rs | 2 +- sdk/iot_hub/src/service/mod.rs | 80 +++++++------------ .../operations/apply_on_edge_device.rs | 12 --- .../src/service/operations/invoke_method.rs | 37 ++------- sdk/iot_hub/src/service/operations/query.rs | 11 --- .../operations/update_or_replace_twin.rs | 4 +- 7 files changed, 40 insertions(+), 110 deletions(-) diff --git a/sdk/iot_hub/examples/directmethod.rs b/sdk/iot_hub/examples/directmethod.rs index a1f8f55f4d..4f8835a3b9 100644 --- a/sdk/iot_hub/examples/directmethod.rs +++ b/sdk/iot_hub/examples/directmethod.rs @@ -32,12 +32,10 @@ async fn main() -> Result<(), Box> { ); let direct_method = service_client.create_module_method( - serde_json::from_str(&payload)?, device_id, module_id, method_name, - 30, - 30, + serde_json::from_str(&payload)?, ); let response = direct_method.into_future().await?; diff --git a/sdk/iot_hub/examples/module_identity.rs b/sdk/iot_hub/examples/module_identity.rs index f070a05b92..3f5f3c100d 100644 --- a/sdk/iot_hub/examples/module_identity.rs +++ b/sdk/iot_hub/examples/module_identity.rs @@ -46,11 +46,11 @@ async fn main() -> Result<(), Box> { &device_id, &module_id, "Docker", - module.etag, AuthenticationMechanism::new_using_symmetric_key( "QhgevIUBSWe37q1MP+M/vtktjOcrE74BVbpcxlLQw58=", "6YS6w5wqkpdfkEW7iOP1NvituehFlFRfPko2n7KY4Gk", ), + module.etag, ) .into_future() .await?; diff --git a/sdk/iot_hub/src/service/mod.rs b/sdk/iot_hub/src/service/mod.rs index 5b5a4d887b..37b1fc71f6 100644 --- a/sdk/iot_hub/src/service/mod.rs +++ b/sdk/iot_hub/src/service/mod.rs @@ -255,29 +255,19 @@ impl ServiceClient { /// # let http_client = azure_core::new_http_client(); /// # let connection_string = "HostName=cool-iot-hub.azure-devices.net;SharedAccessKeyName=iot_hubowner;SharedAccessKey=YSB2ZXJ5IHNlY3VyZSBrZXkgaXMgaW1wb3J0YW50Cg=="; /// let iot_hub = ServiceClient::from_connection_string(http_client, connection_string, 3600).expect("Failed to create the service client!"); - /// let device_method = iot_hub.create_device_method("some-device", "hello-world", 30, 30); + /// let device_method = iot_hub.create_device_method("some-device", "hello-world", serde_json::json!({})); /// ``` pub fn create_device_method( &self, - payload: serde_json::Value, device_id: S, method_name: T, - response_time_out: u64, - connect_time_out: u64, + payload: serde_json::Value, ) -> operations::InvokeMethodBuilder where S: Into, T: Into, { - InvokeMethodBuilder::new( - self.clone(), - payload, - device_id.into(), - None, - method_name.into(), - response_time_out, - connect_time_out, - ) + InvokeMethodBuilder::new(self.clone(), device_id.into(), method_name.into(), payload) } /// Create a new module method @@ -289,31 +279,22 @@ impl ServiceClient { /// # let http_client = azure_core::new_http_client(); /// # let connection_string = "HostName=cool-iot-hub.azure-devices.net;SharedAccessKeyName=iot_hubowner;SharedAccessKey=YSB2ZXJ5IHNlY3VyZSBrZXkgaXMgaW1wb3J0YW50Cg=="; /// let iot_hub = ServiceClient::from_connection_string(http_client, connection_string, 3600).expect("Failed to create the ServiceClient!"); - /// let device_method = iot_hub.create_module_method("some-device", "some-module", "hello-world", 30, 30); + /// let device_method = iot_hub.create_module_method("some-device", "some-module", "hello-world", serde_json::json!({})); /// ``` pub fn create_module_method( &self, - payload: serde_json::Value, device_id: S, module_id: T, method_name: U, - response_time_out: u64, - connect_time_out: u64, + payload: serde_json::Value, ) -> operations::InvokeMethodBuilder where S: Into, T: Into, U: Into, { - InvokeMethodBuilder::new( - self.clone(), - payload, - device_id.into(), - Some(module_id.into()), - method_name.into(), - response_time_out, - connect_time_out, - ) + InvokeMethodBuilder::new(self.clone(), device_id.into(), method_name.into(), payload) + .module_id(module_id.into()) } /// Get the module twin of a given device and module @@ -335,11 +316,6 @@ impl ServiceClient { GetTwinBuilder::new(self.clone(), device_id.into()).module_id(module_id) } - /// Get the HttpClient of the IoTHub service - pub(crate) fn http_client(&self) -> &dyn HttpClient { - self.http_client.as_ref() - } - /// Get the device twin of a given device /// /// ``` @@ -369,8 +345,8 @@ impl ServiceClient { /// let iot_hub = ServiceClient::from_connection_string(http_client, connection_string, 3600).expect("Failed to create the ServiceClient!"); /// let twin = iot_hub.update_module_twin("some-device", "some-module") /// .tag("TagName", "TagValue") - /// .properties(serde_json::json!({"PropertyName": "PropertyValue"})) - /// .execute(); + /// .desired_properties(serde_json::json!({"PropertyName": "PropertyValue"})) + /// .into_future(); /// ``` pub fn update_module_twin(&self, device_id: S, module_id: T) -> UpdateOrReplaceTwinBuilder where @@ -392,8 +368,8 @@ impl ServiceClient { /// let iot_hub = ServiceClient::from_connection_string(http_client, connection_string, 3600).expect("Failed to create the ServiceClient!"); /// let twin = iot_hub.replace_module_twin("some-device", "some-module") /// .tag("TagName", "TagValue") - /// .properties(serde_json::json!({"PropertyName": "PropertyValue"})) - /// .execute(); + /// .desired_properties(serde_json::json!({"PropertyName": "PropertyValue"})) + /// .into_future(); /// ``` pub fn replace_module_twin( &self, @@ -419,8 +395,8 @@ impl ServiceClient { /// let iot_hub = ServiceClient::from_connection_string(http_client, connection_string, 3600).expect("Failed to create the ServiceClient!"); /// let twin = iot_hub.update_device_twin("some-device") /// .tag("TagName", "TagValue") - /// .properties(serde_json::json!({"PropertyName": "PropertyValue"})) - /// .execute(); + /// .desired_properties(serde_json::json!({"PropertyName": "PropertyValue"})) + /// .into_future(); /// ``` pub fn update_device_twin(&self, device_id: S) -> UpdateOrReplaceTwinBuilder where @@ -440,8 +416,8 @@ impl ServiceClient { /// let iot_hub = ServiceClient::from_connection_string(http_client, connection_string, 3600).expect("Failed to create the ServiceClient!"); /// let twin = iot_hub.replace_device_twin("some-device") /// .tag("TagName", "TagValue") - /// .properties(serde_json::json!({"PropertyName": "PropertyValue"})) - /// .execute(); + /// .desired_properties(serde_json::json!({"PropertyName": "PropertyValue"})) + /// .into_future(); /// ``` pub fn replace_device_twin(&self, device_id: S) -> UpdateOrReplaceTwinBuilder where @@ -478,8 +454,8 @@ impl ServiceClient { /// # let http_client = azure_core::new_http_client(); /// # let connection_string = "HostName=cool-iot-hub.azure-devices.net;SharedAccessKeyName=iot_hubowner;SharedAccessKey=YSB2ZXJ5IHNlY3VyZSBrZXkgaXMgaW1wb3J0YW50Cg=="; /// let iot_hub = ServiceClient::from_connection_string(http_client, connection_string, 3600).expect("Failed to create the ServiceClient!"); - /// let device = iot_hub.create_device_identity() - /// .execute("some-existing-device", Status::Enabled, AuthenticationMechanism::new_using_symmetric_key("first-key", "second-key")); + /// let device = iot_hub.create_device_identity("some-existing-device", Status::Enabled, AuthenticationMechanism::new_using_symmetric_key("first-key", "second-key")) + /// .into_future(); /// ``` pub fn create_device_identity( &self, @@ -510,8 +486,7 @@ impl ServiceClient { /// # let http_client = azure_core::new_http_client(); /// # let connection_string = "HostName=cool-iot-hub.azure-devices.net;SharedAccessKeyName=iot_hubowner;SharedAccessKey=YSB2ZXJ5IHNlY3VyZSBrZXkgaXMgaW1wb3J0YW50Cg=="; /// let iot_hub = ServiceClient::from_connection_string(http_client, connection_string, 3600).expect("Failed to create the ServiceClient!"); - /// let device = iot_hub.update_device_identity("etag-of-device-to-update") - /// .execute("some-existing-device", Status::Enabled, AuthenticationMechanism::new_using_symmetric_key("first-key", "second-key")); + /// let device = iot_hub.update_device_identity("some-existing-device", Status::Enabled, AuthenticationMechanism::new_using_symmetric_key("first-key", "second-key"), "etag-of-device-to-update"); /// ``` pub fn update_device_identity( &self, @@ -585,8 +560,7 @@ impl ServiceClient { /// # let http_client = azure_core::new_http_client(); /// # let connection_string = "HostName=cool-iot-hub.azure-devices.net;SharedAccessKeyName=iot_hubowner;SharedAccessKey=YSB2ZXJ5IHNlY3VyZSBrZXkgaXMgaW1wb3J0YW50Cg=="; /// let iot_hub = ServiceClient::from_connection_string(http_client, connection_string, 3600).expect("Failed to create the ServiceClient!"); - /// let device = iot_hub.create_module_identity() - /// .execute("some-existing-device", "some-existing-module", "IoTEdge", AuthenticationMechanism::new_using_symmetric_key("first-key", "second-key")); + /// let device = iot_hub.create_module_identity("some-existing-device", "some-existing-module", "IoTEdge", AuthenticationMechanism::new_using_symmetric_key("first-key", "second-key")).into_future(); /// ``` pub fn create_module_identity( &self, @@ -621,16 +595,15 @@ impl ServiceClient { /// # let http_client = azure_core::new_http_client(); /// # let connection_string = "HostName=cool-iot-hub.azure-devices.net;SharedAccessKeyName=iot_hubowner;SharedAccessKey=YSB2ZXJ5IHNlY3VyZSBrZXkgaXMgaW1wb3J0YW50Cg=="; /// let iot_hub = ServiceClient::from_connection_string(http_client, connection_string, 3600).expect("Failed to create the ServiceClient!"); - /// let device = iot_hub.update_module_identity("etag-of-device-to-update") - /// .execute("some-existing-device", "some-existing-module", "IoTEdge", AuthenticationMechanism::new_using_symmetric_key("first-key", "second-key")); + /// let device = iot_hub.update_module_identity("some-existing-device", "some-existing-module", "IoTEdge", AuthenticationMechanism::new_using_symmetric_key("first-key", "second-key"), "etag-of-device-to-update"); /// ``` pub fn update_module_identity( &self, device_id: S1, module_id: S2, managed_by: S3, - etag: S4, authentication: AuthenticationMechanism, + etag: S4, ) -> CreateOrUpdateModuleIdentityBuilder where S1: Into, @@ -691,7 +664,7 @@ impl ServiceClient { /// # let http_client = azure_core::new_http_client(); /// # let connection_string = "HostName=cool-iot-hub.azure-devices.net;SharedAccessKeyName=iot_hubowner;SharedAccessKey=YSB2ZXJ5IHNlY3VyZSBrZXkgaXMgaW1wb3J0YW50Cg=="; /// let iot_hub = ServiceClient::from_connection_string(http_client, connection_string, 3600).expect("Failed to create the ServiceClient!"); - /// let query_builder = iot_hub.query(); + /// let query_builder = iot_hub.query("$SOME_QUERY"); /// ``` pub fn query(&self, query: Q) -> QueryBuilder where @@ -762,7 +735,7 @@ impl ServiceClient { /// # let connection_string = "HostName=cool-iot-hub.azure-devices.net;SharedAccessKeyName=iot_hubowner;SharedAccessKey=YSB2ZXJ5IHNlY3VyZSBrZXkgaXMgaW1wb3J0YW50Cg=="; /// let iot_hub = ServiceClient::from_connection_string(http_client, connection_string, 3600).expect("Failed to create the ServiceClient!"); /// let configuration = iot_hub.create_configuration("some-configuration-id", 10, "tags.environment='test'") - /// .execute(); + /// .into_future(); /// ``` pub fn create_configuration( &self, @@ -794,7 +767,7 @@ impl ServiceClient { /// # let connection_string = "HostName=cool-iot-hub.azure-devices.net;SharedAccessKeyName=iot_hubowner;SharedAccessKey=YSB2ZXJ5IHNlY3VyZSBrZXkgaXMgaW1wb3J0YW50Cg=="; /// let iot_hub = ServiceClient::from_connection_string(http_client, connection_string, 3600).expect("Failed to create the ServiceClient!"); /// let configuration = iot_hub.update_configuration("some-configuration-id", 10, "tags.environment='test'", "some-etag-value") - /// .execute(); + /// .into_future(); /// ``` pub fn update_configuration( &self, @@ -854,6 +827,11 @@ impl ServiceClient { request.insert_headers(&ContentType::APPLICATION_JSON); Ok(request) } + + /// Get the HttpClient of the IoTHub service + pub(crate) fn http_client(&self) -> &dyn HttpClient { + self.http_client.as_ref() + } } #[cfg(test)] diff --git a/sdk/iot_hub/src/service/operations/apply_on_edge_device.rs b/sdk/iot_hub/src/service/operations/apply_on_edge_device.rs index 6f38d61bb2..2ca449ff45 100644 --- a/sdk/iot_hub/src/service/operations/apply_on_edge_device.rs +++ b/sdk/iot_hub/src/service/operations/apply_on_edge_device.rs @@ -15,18 +15,6 @@ operation! { impl ApplyOnEdgeDeviceBuilder { /// Performs the apply on edge device request - /// - /// - /// ``` - /// use azure_iot_hub::service::ServiceClient; - /// use serde_json; - /// - /// # let connection_string = "HostName=cool-iot-hub.azure-devices.net;SharedAccessKeyName=iot_hubowner;SharedAccessKey=YSB2ZXJ5IHNlY3VyZSBrZXkgaXMgaW1wb3J0YW50Cg=="; - /// # let http_client = azure_core::new_http_client(); - /// - /// let iot_hub = ServiceClient::from_connection_string(http_client, connection_string, 3600).expect("Failed to create the ServiceClient!"); - /// iot_hub.apply_on_edge_device("some-device").execute(); - /// ``` pub fn into_future(self) -> ApplyOnEdgeDevice { Box::pin(async move { let uri = format!( diff --git a/sdk/iot_hub/src/service/operations/invoke_method.rs b/sdk/iot_hub/src/service/operations/invoke_method.rs index 38a4d72573..868e6a6aa3 100644 --- a/sdk/iot_hub/src/service/operations/invoke_method.rs +++ b/sdk/iot_hub/src/service/operations/invoke_method.rs @@ -9,39 +9,16 @@ azure_core::operation! { /// invoke a module or device method. InvokeMethod, client: ServiceClient, - payload: serde_json::Value, device_id: String, - module_id: Option, method_name: String, - response_time_out: u64, - connect_time_out: u64, + payload: serde_json::Value, + ?module_id: String, + ?response_time_out: u64, + ?connect_time_out: u64 } impl InvokeMethodBuilder { - /// Invoke the DirectMethod - /// - /// Either a module method, or device method is invoked based on the - /// way the DirectMethod was created. On invocation a DirectMethodResponse - /// is returned. This does not mean the invocation was successfull. The status - /// code within the DirectMethodResponse should still be verified. - /// - /// # Examples - /// ``` - /// # use std::sync::Arc; - /// # use azure_core::HttpClient; - /// use azure_iot_hub::service::ServiceClient; - /// # let http_client = azure_core::new_http_client(); - /// - /// let service = ServiceClient::from_sas_token(http_client, "some-iot-hub", "sas_token"); - /// let great_method = service.create_device_method( - /// "SomeDeviceId", - /// "GreatMethod", - /// 100, - /// 60 - /// ); - /// - /// great_method.execute(serde_json::json!({"hello": "world"})); - /// ``` + /// Turn the builder into a `Future` pub fn into_future(self) -> InvokeMethod { Box::pin(async move { let uri = match &self.module_id { @@ -57,10 +34,10 @@ impl InvokeMethodBuilder { let mut request = self.client.finalize_request(&uri, Method::Post)?; let method = InvokeMethodBody { - connect_timeout_in_seconds: self.connect_time_out, + connect_timeout_in_seconds: self.connect_time_out.unwrap_or(15), method_name: &self.method_name, payload: self.payload, - response_timeout_in_seconds: self.response_time_out, + response_timeout_in_seconds: self.response_time_out.unwrap_or(15), }; let body = azure_core::to_json(&method)?; diff --git a/sdk/iot_hub/src/service/operations/query.rs b/sdk/iot_hub/src/service/operations/query.rs index 577c11a69d..d83478d8e0 100644 --- a/sdk/iot_hub/src/service/operations/query.rs +++ b/sdk/iot_hub/src/service/operations/query.rs @@ -23,17 +23,6 @@ azure_core::operation! { impl QueryBuilder { /// Invoke a qiven query on the IoT Hub - /// - /// ``` - /// use std::sync::Arc; - /// use azure_core::HttpClient; - /// use azure_iot_hub::service::ServiceClient; - /// - /// # let http_client = azure_core::new_http_client(); - /// # let connection_string = "HostName=cool-iot-hub.azure-devices.net;SharedAccessKeyName=iot_hubowner;SharedAccessKey=YSB2ZXJ5IHNlY3VyZSBrZXkgaXMgaW1wb3J0YW50Cg=="; - /// let iot_hub = ServiceClient::from_connection_string(http_client, connection_string, 3600).expect("Failed to create the ServiceClient!"); - /// let query_builder = iot_hub.query().max_item_count(1).continuation("some_token").execute("SELECT * FROM devices"); - /// ``` pub fn into_future(self) -> Query { Box::pin(async move { let uri = format!( diff --git a/sdk/iot_hub/src/service/operations/update_or_replace_twin.rs b/sdk/iot_hub/src/service/operations/update_or_replace_twin.rs index 011eb99fd8..f5538875fe 100644 --- a/sdk/iot_hub/src/service/operations/update_or_replace_twin.rs +++ b/sdk/iot_hub/src/service/operations/update_or_replace_twin.rs @@ -55,8 +55,8 @@ impl UpdateOrReplaceTwinBuilder { /// let iot_hub = ServiceClient::from_connection_string(http_client, connection_string, 3600).expect("Failed to create the ServiceClient!"); /// let twin = iot_hub.update_device_twin("some-device") /// .tag("TagName", "TagValue") - /// .properties(serde_json::json!({"PropertyName": "PropertyValue"})) - /// .execute(); + /// .desired_properties(serde_json::json!({"PropertyName": "PropertyValue"})) + /// .into_future(); /// ``` pub fn into_future(self) -> UpdateOrReplaceTwin { Box::pin(async move {