diff --git a/services/autorust/codegen/examples/gen_mgmt.rs b/services/autorust/codegen/examples/gen_mgmt.rs index 05c381e0b2..97493abc24 100644 --- a/services/autorust/codegen/examples/gen_mgmt.rs +++ b/services/autorust/codegen/examples/gen_mgmt.rs @@ -5,7 +5,7 @@ use std::{collections::HashSet, fs, path::PathBuf}; const OUTPUT_FOLDER: &str = "../mgmt"; -const ONLY_SERVICES: &[&str] = &[]; +const ONLY_SERVICES: &[&str] = &["vmware"]; const SKIP_SERVICES: &[&str] = &[ "datamigration", diff --git a/services/mgmt/vmware/Cargo.toml b/services/mgmt/vmware/Cargo.toml index b62063e066..b73209496e 100644 --- a/services/mgmt/vmware/Cargo.toml +++ b/services/mgmt/vmware/Cargo.toml @@ -12,6 +12,7 @@ bytes = "1.0" thiserror = "1.0" http = "0.2" url = "2.2" +futures = "0.3" [dev-dependencies] azure_identity = { path = "../../../sdk/identity", version = "0.1.0" } diff --git a/services/mgmt/vmware/examples/private_cloud_list.rs b/services/mgmt/vmware/examples/private_cloud_list.rs index ec4f28381a..bada7d9f0e 100644 --- a/services/mgmt/vmware/examples/private_cloud_list.rs +++ b/services/mgmt/vmware/examples/private_cloud_list.rs @@ -11,19 +11,24 @@ cargo run --package azure_mgmt_vmware --example private_cloud_list */ use azure_identity::token_credentials::AzureCliCredential; -use azure_mgmt_vmware::operations::private_clouds; +use std::sync::Arc; #[tokio::main] async fn main() -> Result<(), Box> { - let http_client = azure_core::new_http_client(); - let token_credential = AzureCliCredential {}; - let subscription_id = &AzureCliCredential::get_subscription()?; - let config = &azure_mgmt_vmware::config(http_client, Box::new(token_credential)).build(); + let credential = Arc::new(AzureCliCredential {}); + let client = azure_mgmt_vmware::ClientBuilder::new(credential).build(); - let clouds = private_clouds::list_in_subscription(config, subscription_id).await?; - println!("# of private clouds {}", clouds.value.len()); - for cloud in &clouds.value { - println!("{:?}", cloud.tracked_resource.resource.id); - } + let name = "George"; // allow passing a reference for parameters + let ops = client.operations().list(name).into_future().await?; + println!("# of operations{}", ops.value.len()); + + // let subscription_id = &AzureCliCredential::get_subscription()?; + // let config = &azure_mgmt_vmware::config(http_client, Box::new(credential)).build(); + + // let clouds = private_clouds::list_in_subscription(config, subscription_id).await?; + // println!("# of private clouds {}", clouds.value.len()); + // for cloud in &clouds.value { + // println!("{:?}", cloud.tracked_resource.resource.id); + // } Ok(()) } diff --git a/services/mgmt/vmware/src/lib.rs b/services/mgmt/vmware/src/lib.rs index 24085630e9..e8f908b142 100644 --- a/services/mgmt/vmware/src/lib.rs +++ b/services/mgmt/vmware/src/lib.rs @@ -6,7 +6,7 @@ #[cfg(feature = "package-2021-12-01")] pub mod package_2021_12_01; #[cfg(all(feature = "package-2021-12-01", not(feature = "no-default-version")))] -pub use package_2021_12_01::{models, operations, operations::Error}; +pub use package_2021_12_01::{models, operations, operations::Client, operations::ClientBuilder, operations::Error}; #[cfg(feature = "package-2021-06-01")] pub mod package_2021_06_01; #[cfg(all(feature = "package-2021-06-01", not(feature = "no-default-version")))] diff --git a/services/mgmt/vmware/src/package_2021_12_01/operations.rs b/services/mgmt/vmware/src/package_2021_12_01/operations.rs index 793b93d303..301ef4b822 100644 --- a/services/mgmt/vmware/src/package_2021_12_01/operations.rs +++ b/services/mgmt/vmware/src/package_2021_12_01/operations.rs @@ -2,6 +2,8 @@ #![allow(unused_mut)] #![allow(unused_variables)] #![allow(unused_imports)] +use std::ops::Deref; + use super::{models, API_VERSION}; #[non_exhaustive] #[derive(Debug, thiserror :: Error)] @@ -200,46 +202,150 @@ pub enum Error { #[error(transparent)] ScriptExecutions_GetExecutionLogs(#[from] script_executions::get_execution_logs::Error), } + +#[derive(Clone)] +pub struct Client { + endpoint: String, + credential: std::sync::Arc, + scopes: Vec, + pipeline: azure_core::pipeline::Pipeline, +} + +pub struct ClientBuilder { + credential: std::sync::Arc, + endpoint: Option, + scopes: Option>, +} + +pub const DEFAULT_ENDPOINT: &str = azure_core::resource_manager_endpoint::AZURE_PUBLIC_CLOUD; + +impl ClientBuilder { + pub fn new(credential: std::sync::Arc) -> Self { + Self { + credential, + endpoint: None, + scopes: None, + } + } + + pub fn endpoint(mut self, endpoint: impl Into) { + self.endpoint = Some(endpoint.into()); + } + + pub fn scopes(mut self, scopes: &[&str]) { + self.scopes = Some(scopes.iter().map(|scope| (*scope).to_owned()).collect()); + } + + pub fn build(self) -> Client { + let endpoint = self.endpoint.unwrap_or_else(|| DEFAULT_ENDPOINT.to_owned()); + let scopes = self.scopes.unwrap_or_else(|| vec![format!("{}/", endpoint)]); + Client::new(endpoint, self.credential, scopes) + } +} + +impl Client { + pub fn endpoint(&self) -> &str { + self.endpoint.as_str() + } + pub fn credential(&self) -> &dyn azure_core::TokenCredential { + self.credential.as_ref() + } + pub fn scopes(&self) -> Vec<&str> { + self.scopes.iter().map(String::as_str).collect() + } + pub(crate) async fn send(&self, request: impl Into) -> Result { + let mut context = azure_core::Context::default(); + let mut request = request.into(); + self.pipeline.send(&mut context, &mut request).await + } +} + +impl Client { + pub fn new(endpoint: String, credential: std::sync::Arc, scopes: Vec) -> Self { + let pipeline = azure_core::pipeline::Pipeline::new( + option_env!("CARGO_PKG_NAME"), + option_env!("CARGO_PKG_VERSION"), + azure_core::ClientOptions::default(), + Vec::new(), + Vec::new(), + ); + Self { + endpoint, + credential, + scopes, + pipeline, + } + } + + pub fn operations(&self) -> operations::Client { + operations::Client(self.clone()) + } +} + pub mod operations { use super::{models, API_VERSION}; - pub async fn list(operation_config: &crate::OperationConfig) -> std::result::Result { - let http_client = operation_config.http_client(); - let url_str = &format!("{}/providers/Microsoft.AVS/operations", operation_config.base_path(),); - let mut url = url::Url::parse(url_str).map_err(list::Error::ParseUrlError)?; - let mut req_builder = http::request::Builder::new(); - req_builder = req_builder.method(http::Method::GET); - if let Some(token_credential) = operation_config.token_credential() { - let token_response = token_credential - .get_token(operation_config.token_credential_resource()) - .await - .map_err(list::Error::GetTokenError)?; - req_builder = req_builder.header(http::header::AUTHORIZATION, format!("Bearer {}", token_response.token.secret())); - } - url.query_pairs_mut().append_pair("api-version", super::API_VERSION); - let req_body = bytes::Bytes::from_static(azure_core::EMPTY_BODY); - req_builder = req_builder.uri(url.as_str()); - let req = req_builder.body(req_body).map_err(list::Error::BuildRequestError)?; - let rsp = http_client.execute_request(req).await.map_err(list::Error::ExecuteRequestError)?; - match rsp.status() { - http::StatusCode::OK => { - let rsp_body = rsp.body(); - let rsp_value: models::OperationList = - serde_json::from_slice(rsp_body).map_err(|source| list::Error::DeserializeError(source, rsp_body.clone()))?; - Ok(rsp_value) - } - status_code => { - let rsp_body = rsp.body(); - let rsp_value: models::CloudError = - serde_json::from_slice(rsp_body).map_err(|source| list::Error::DeserializeError(source, rsp_body.clone()))?; - Err(list::Error::DefaultResponse { - status_code, - value: rsp_value, - }) - } + + pub struct Client(pub(crate) super::Client); + + impl Client { + pub fn list<'a>(&'a self, name: &'a str) -> list::Builder { + list::Builder { client: self.0.clone(), name } } } + pub mod list { use super::{models, API_VERSION}; + + #[derive(Clone)] + pub struct Builder<'a> { + pub(crate) client: crate::operations::Client, + pub(crate) name: &'a str, + } + + impl<'a> Builder<'a> { + pub fn into_future(self) -> futures::future::BoxFuture<'a, std::result::Result> { + Box::pin(async move { + let url_str = &format!("{}/providers/Microsoft.AVS/operations?name={}", &self.client.endpoint, self.name); + let mut url = url::Url::parse(url_str).map_err(Error::ParseUrlError)?; + let mut req_builder = http::request::Builder::new(); + req_builder = req_builder.method(http::Method::GET); + let credential = self.client.credential(); + let token_response = credential + .get_token(&self.client.scopes().join(" ")) + .await + .map_err(Error::GetTokenError)?; + req_builder = req_builder.header(http::header::AUTHORIZATION, format!("Bearer {}", token_response.token.secret())); + url.query_pairs_mut().append_pair("api-version", super::API_VERSION); + let req_body = bytes::Bytes::from_static(azure_core::EMPTY_BODY); + req_builder = req_builder.uri(url.as_str()); + let req = req_builder.body(req_body).map_err(Error::BuildRequestError)?; + let rsp = self.client.send(req).await.map_err(Error::SendError)?; + let (rsp_status, rsp_headers, rsp_stream) = rsp.deconstruct(); + match rsp_status { + http::StatusCode::OK => { + let rsp_body = azure_core::collect_pinned_stream(rsp_stream) + .await + .map_err(Error::ResponseBytesError)?; + let rsp_value: models::OperationList = + serde_json::from_slice(&rsp_body).map_err(|source| Error::DeserializeError(source, rsp_body.clone()))?; + Ok(rsp_value) + } + status_code => { + let rsp_body = azure_core::collect_pinned_stream(rsp_stream) + .await + .map_err(Error::ResponseBytesError)?; + let rsp_value: models::CloudError = + serde_json::from_slice(&rsp_body).map_err(|source| Error::DeserializeError(source, rsp_body.clone()))?; + Err(Error::DefaultResponse { + status_code, + value: rsp_value, + }) + } + } + }) + } + } + #[derive(Debug, thiserror :: Error)] pub enum Error { #[error("HTTP status code {}", status_code)] @@ -252,7 +358,9 @@ pub mod operations { #[error("Failed to build request: {0}")] BuildRequestError(http::Error), #[error("Failed to execute request: {0}")] - ExecuteRequestError(azure_core::HttpError), + SendError(azure_core::Error), + #[error("Failed to get response bytes: {0}")] + ResponseBytesError(azure_core::StreamError), #[error("Failed to serialize request body: {0}")] SerializeError(serde_json::Error), #[error("Failed to deserialize response: {0}, body: {1:?}")]