Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Always return Result<Arc<Self>> from new credential constructors #1828

Merged
merged 3 commits into from
Sep 27, 2024
Merged
Show file tree
Hide file tree
Changes from 2 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions sdk/core/azure_core_amqp/src/fe2o3/messaging/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -655,7 +655,7 @@ mod tests {
>::new(
seq.into_iter()
.map(|x| {
let iter = x.into_iter().map(|y| y.into());
let iter = x.into_iter().map(Into::into);
iter.collect::<fe2o3_amqp_types::primitives::List<fe2o3_amqp_types::primitives::Value>>().into()
})
.collect::<Vec<
Expand All @@ -678,7 +678,7 @@ mod tests {
// AmqpMessageBody::Sequence(
// test_body
// .into_iter()
// .map(|x| x.into_iter().map(|y| y.into()).collect())
// .map(|x| x.into_iter().map(Into::into).collect())
// .collect()
// )
// );
Expand Down
9 changes: 5 additions & 4 deletions sdk/core/azure_core_amqp/src/messaging.rs
Original file line number Diff line number Diff line change
Expand Up @@ -892,6 +892,7 @@ impl From<AmqpMessageProperties> for AmqpList {
}
}

#[allow(clippy::vec_init_then_push)]
#[test]
fn test_size_of_serialized_timestamp() {
let timestamp = fe2o3_amqp_types::primitives::Timestamp::from_milliseconds(12345);
Expand Down Expand Up @@ -1544,13 +1545,13 @@ mod tests {
.with_delivery_count(3)
.build();

assert_eq!(header.durable, true);
assert!(header.durable);
assert_eq!(header.priority, 5);
assert_eq!(
header.time_to_live,
Some(std::time::Duration::from_millis(1000))
);
assert_eq!(header.first_acquirer, false);
assert!(!header.first_acquirer);
assert_eq!(header.delivery_count, 3);
}

Expand All @@ -1559,7 +1560,7 @@ mod tests {
{
let c_serialized = vec![0x00, 0x53, 0x70, 0xc0, 0x04, 0x02, 0x40, 0x50, 0x05];
let deserialized_from_c: fe2o3_amqp_types::messaging::Header =
serde_amqp::de::from_slice(&c_serialized.as_slice()).unwrap();
serde_amqp::de::from_slice(c_serialized.as_slice()).unwrap();

let header = fe2o3_amqp_types::messaging::Header::builder()
.priority(Priority::from(5))
Expand All @@ -1568,7 +1569,7 @@ mod tests {

assert_eq!(c_serialized, serialized);
let deserialized: fe2o3_amqp_types::messaging::Header =
serde_amqp::de::from_slice(&serialized.as_slice()).unwrap();
serde_amqp::de::from_slice(serialized.as_slice()).unwrap();

assert_eq!(c_serialized, serialized);
assert_eq!(header, deserialized);
Expand Down
4 changes: 2 additions & 2 deletions sdk/core/azure_core_amqp/src/receiver.rs
Original file line number Diff line number Diff line change
Expand Up @@ -257,7 +257,7 @@ mod tests {
.with_auto_accept(true)
.build();

assert_eq!(receiver_options.auto_accept, true);
assert!(receiver_options.auto_accept);
}

#[test]
Expand Down Expand Up @@ -297,6 +297,6 @@ mod tests {
receiver_options.credit_mode.unwrap(),
ReceiverCreditMode::Manual
);
assert_eq!(receiver_options.auto_accept, false);
assert!(!receiver_options.auto_accept);
}
}
10 changes: 5 additions & 5 deletions sdk/core/azure_core_amqp/src/value.rs
Original file line number Diff line number Diff line change
Expand Up @@ -594,8 +594,7 @@ mod tests {
let v: AmqpValue = AmqpValue::Null;
assert_eq!(v, AmqpValue::Null);
assert_eq!(AmqpValue::Null, v);
let b: () = v.into();
assert_eq!(b, ());
let _: () = v.into();
}

{
Expand All @@ -604,6 +603,7 @@ mod tests {
}
}

#[allow(clippy::approx_constant)]
#[test]
fn test_amqp_ordered_map() {
let mut map = AmqpOrderedMap::new();
Expand All @@ -621,21 +621,21 @@ mod tests {
assert_eq!(map.get("key1"), None);
}

#[allow(clippy::approx_constant)]
#[test]
fn test_amqp_value() {
// Test AmqpValue::Null
let null_value: AmqpValue = AmqpValue::Null;
assert_eq!(null_value, AmqpValue::Null);
assert_eq!(AmqpValue::Null, null_value);
let null_unit: () = null_value.into();
assert_eq!(null_unit, ());
let _: () = null_value.into();

// Test AmqpValue::Boolean
let bool_value: AmqpValue = AmqpValue::Boolean(true);
assert_eq!(bool_value, AmqpValue::Boolean(true));
assert_eq!(AmqpValue::Boolean(true), bool_value);
let bool_val: bool = bool_value.into();
assert_eq!(bool_val, true);
assert!(bool_val);

// Test AmqpValue::UByte
let ubyte_value: AmqpValue = AmqpValue::UByte(255);
Expand Down
19 changes: 9 additions & 10 deletions sdk/cosmos/azure_data_cosmos/examples/cosmos_metadata.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,6 @@ use azure_data_cosmos::{
CosmosClient, CosmosClientMethods,
};
use clap::Parser;
use std::sync::Arc;

/// A simple example to show connecting to a Cosmos DB Account and retrieving the properties of a database.
#[derive(Parser)]
Expand All @@ -29,13 +28,13 @@ pub struct Args {

#[tokio::main]
pub async fn main() -> Result<(), Box<dyn std::error::Error>> {
let _ = tracing_subscriber::fmt()
tracing_subscriber::fmt()
.with_env_filter(tracing_subscriber::EnvFilter::from_default_env())
.init();

let args = Args::parse();

let client = create_client(&args);
let client = create_client(&args)?;

let db_client = client.database_client(&args.database);
if let Some(container_name) = args.container {
Expand All @@ -55,17 +54,17 @@ pub async fn main() -> Result<(), Box<dyn std::error::Error>> {
}

#[cfg(feature = "key_auth")]
fn create_client(args: &Args) -> CosmosClient {
fn create_client(args: &Args) -> azure_core::Result<CosmosClient> {
if let Some(key) = args.key.as_ref() {
CosmosClient::with_key(&args.endpoint, key.clone(), None).unwrap()
CosmosClient::with_key(&args.endpoint, key.clone(), None)
} else {
let cred = Arc::new(azure_identity::DefaultAzureCredential::new().unwrap());
CosmosClient::new(&args.endpoint, cred, None).unwrap()
let cred = azure_identity::DefaultAzureCredential::new()?;
CosmosClient::new(&args.endpoint, cred, None)
}
}

#[cfg(not(feature = "key_auth"))]
fn create_client(args: &Args) -> CosmosClient {
let cred = Arc::new(azure_identity::DefaultAzureCredential::new().unwrap());
CosmosClient::new(&args.endpoint, cred, None).unwrap()
fn create_client(args: &Args) -> azure_core::Result<CosmosClient> {
let cred = azure_identity::DefaultAzureCredential::new()?;
CosmosClient::new(&args.endpoint, cred, None)
}
19 changes: 9 additions & 10 deletions sdk/cosmos/azure_data_cosmos/examples/cosmos_query.rs
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,6 @@ use azure_data_cosmos::{
use azure_identity::DefaultAzureCredential;
use clap::Parser;
use futures::StreamExt;
use std::sync::Arc;

/// An example to show querying a Cosmos DB container.
#[derive(Parser)]
Expand Down Expand Up @@ -38,13 +37,13 @@ pub struct Args {

#[tokio::main]
pub async fn main() -> Result<(), Box<dyn std::error::Error>> {
let _ = tracing_subscriber::fmt()
tracing_subscriber::fmt()
.with_env_filter(tracing_subscriber::EnvFilter::from_default_env())
.init();

let args = Args::parse();

let client = create_client(&args);
let client = create_client(&args)?;

let db_client = client.database_client(&args.database);
let container_client = db_client.container_client(&args.container);
Expand All @@ -67,17 +66,17 @@ pub async fn main() -> Result<(), Box<dyn std::error::Error>> {
}

#[cfg(feature = "key_auth")]
fn create_client(args: &Args) -> CosmosClient {
fn create_client(args: &Args) -> azure_core::Result<CosmosClient> {
if let Some(key) = args.key.as_ref() {
CosmosClient::with_key(&args.endpoint, key.clone(), None).unwrap()
CosmosClient::with_key(&args.endpoint, key.clone(), None)
} else {
let cred = DefaultAzureCredential::new().map(Arc::new).unwrap();
CosmosClient::new(&args.endpoint, cred, None).unwrap()
let cred = DefaultAzureCredential::new()?;
CosmosClient::new(&args.endpoint, cred, None)
}
}

#[cfg(not(feature = "key_auth"))]
fn create_client(args: &Args) -> CosmosClient {
let cred = DefaultAzureCredential::new().map(Arc::new).unwrap();
CosmosClient::new(&args.endpoint, cred, None).unwrap()
fn create_client(args: &Args) -> azure_core::Result<CosmosClient> {
let cred = DefaultAzureCredential::new()?;
CosmosClient::new(&args.endpoint, cred, None)
}
Original file line number Diff line number Diff line change
Expand Up @@ -48,7 +48,7 @@ impl CosmosClient {
/// # use std::sync::Arc;
/// use azure_data_cosmos::CosmosClient;
///
/// let credential = azure_identity::DefaultAzureCredential::new().map(Arc::new).unwrap();
/// let credential = azure_identity::DefaultAzureCredential::new().unwrap();
/// let client = CosmosClient::new("https://myaccount.documents.azure.com/", credential, None).unwrap();
/// ```
pub fn new(
Expand Down
2 changes: 1 addition & 1 deletion sdk/cosmos/azure_data_cosmos/src/query.rs
Original file line number Diff line number Diff line change
Expand Up @@ -150,7 +150,7 @@ mod tests {
.with_parameter("float_param", 4.2)?
.with_parameter("bool_param", true)?
.with_parameter("obj_param", obj_param)?
.with_parameter("arr_param", &["a", "b", "c"])?
.with_parameter("arr_param", ["a", "b", "c"])?
.with_parameter("null_option", null_option)?
.with_parameter("null_value", ())?;
let serialized = serde_json::to_string(&query).unwrap();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ async fn main() -> Result<()> {
let host = env::var("EVENTHUBS_HOST").unwrap();
let eventhub = env::var("EVENTHUB_NAME").unwrap();

let credential = DefaultAzureCredential::new().unwrap();
let credential = DefaultAzureCredential::new()?;

let client = ProducerClient::new(
host,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ async fn main() -> Result<()> {
let host = env::var("EVENTHUBS_HOST").unwrap();
let eventhub = env::var("EVENTHUB_NAME").unwrap();

let credential = DefaultAzureCredential::new().unwrap();
let credential = DefaultAzureCredential::new()?;

let client = ProducerClient::new(
host,
Expand Down
6 changes: 3 additions & 3 deletions sdk/eventhubs/azure_messaging_eventhubs/src/consumer/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,7 @@ pub struct ConsumerClient {
session_instances: Mutex<HashMap<String, Arc<AmqpSession>>>,
mgmt_client: Mutex<OnceLock<ManagementInstance>>,
connection: OnceLock<AmqpConnection>,
credential: Box<dyn azure_core::credentials::TokenCredential>,
credential: Arc<dyn azure_core::credentials::TokenCredential>,
eventhub: String,
url: String,
authorization_scopes: Mutex<HashMap<String, AccessToken>>,
Expand Down Expand Up @@ -84,7 +84,7 @@ impl ConsumerClient {
fully_qualified_namespace: impl Into<String> + Debug,
eventhub_name: impl Into<String> + Debug,
consumer_group: Option<String>,
credential: impl TokenCredential + 'static,
credential: Arc<dyn TokenCredential>,
options: Option<ConsumerClientOptions>,
) -> Self {
let eventhub_name = eventhub_name.into();
Expand All @@ -100,7 +100,7 @@ impl ConsumerClient {
session_instances: Mutex::new(HashMap::new()),
mgmt_client: Mutex::new(OnceLock::new()),
connection: OnceLock::new(),
credential: Box::new(credential),
credential,
eventhub: eventhub_name,
url,
authorization_scopes: Mutex::new(HashMap::new()),
Expand Down
8 changes: 4 additions & 4 deletions sdk/eventhubs/azure_messaging_eventhubs/src/producer/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -26,8 +26,8 @@ use azure_core::{
error::{Error, Result},
};
use batch::{EventDataBatch, EventDataBatchOptions};
use std::collections::HashMap;
use std::sync::{Arc, OnceLock};
use std::{boxed::Box, collections::HashMap};
use tracing::{debug, trace};
use url::Url;

Expand Down Expand Up @@ -86,7 +86,7 @@ pub struct ProducerClient {
sender_instances: Mutex<HashMap<String, SenderInstance>>,
mgmt_client: Mutex<OnceLock<ManagementInstance>>,
connection: OnceLock<AmqpConnection>,
credential: Box<dyn azure_core::credentials::TokenCredential>,
credential: Arc<dyn azure_core::credentials::TokenCredential>,
eventhub: String,
url: String,
authorization_scopes: Mutex<HashMap<String, AccessToken>>,
Expand All @@ -108,15 +108,15 @@ impl ProducerClient {
pub fn new(
fully_qualified_namespace: impl Into<String>,
eventhub: impl Into<String>,
credential: impl azure_core::credentials::TokenCredential + 'static,
credential: Arc<dyn azure_core::credentials::TokenCredential>,
options: ProducerClientOptions,
) -> Self {
let eventhub: String = eventhub.into();
let fully_qualified_namespace: String = fully_qualified_namespace.into();
Self {
options,
connection: OnceLock::new(),
credential: Box::new(credential),
credential: credential.clone(),
url: format!("amqps://{}/{}", fully_qualified_namespace, eventhub),
eventhub,
authorization_scopes: Mutex::new(HashMap::new()),
Expand Down
60 changes: 31 additions & 29 deletions sdk/identity/azure_identity/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,41 +5,43 @@ Azure Identity crate for the unofficial Microsoft Azure SDK for Rust. This crate
This crate provides several implementations of the [azure_core::auth::TokenCredential](https://docs.rs/azure_core/latest/azure_core/auth/trait.TokenCredential.html) trait.
It is recommended to start with `azure_identity::create_credential()?`, which will create an instance of `DefaultAzureCredential` by default. If you want to use a specific credential type, the `AZURE_CREDENTIAL_KIND` environment variable may be set to a value from `azure_credential_kinds`, such as `azurecli` or `virtualmachine`.

```rust
```rust,no_run
use azure_core::credentials::TokenCredential;
use std::sync::Arc;

#[tokio::main]
async fn main() -> Result<(), Box<dyn std::error::Error>> {
let subscription_id =
std::env::var("AZURE_SUBSCRIPTION_ID").expect("AZURE_SUBSCRIPTION_ID required");

let credential = azure_identity::create_credential()?;

// Let's enumerate the Azure storage accounts in the subscription using the REST API directly.
// This is just an example. It is easier to use the Azure SDK for Rust crates.
let url = url::Url::parse(&format!("https://management.azure.com/subscriptions/{subscription_id}/providers/Microsoft.Storage/storageAccounts?api-version=2019-06-01"))?;

let access_token = credential
.get_token(&["https://management.azure.com/.default"])
.await?;

let response = reqwest::Client::new()
.get(url)
.header(
"Authorization",
format!("Bearer {}", access_token.token.secret()),
)
.send()
.await?
.text()
.await?;

println!("{response}");
Ok(())
let subscription_id =
std::env::var("AZURE_SUBSCRIPTION_ID").expect("AZURE_SUBSCRIPTION_ID required");

let credential: Arc<dyn TokenCredential> = azure_identity::DefaultAzureCredential::new()?;

// Let's enumerate the Azure storage accounts in the subscription using the REST API directly.
// This is just an example. It is easier to use the Azure SDK for Rust crates.
let url = url::Url::parse(&format!("https://management.azure.com/subscriptions/{subscription_id}/providers/Microsoft.Storage/storageAccounts?api-version=2019-06-01"))?;

let access_token = credential
.get_token(&["https://management.azure.com/.default"])
.await?;

let response = reqwest::Client::new()
.get(url)
.header(
"Authorization",
format!("Bearer {}", access_token.token.secret()),
)
.send()
.await?
.text()
.await?;

println!("{response}");
Ok(())
}
```

The supported authentication flows are:

* [Authorization code flow](https://docs.microsoft.com/azure/active-directory/develop/v2-oauth2-auth-code-flow).
* [Client credentials flow](https://docs.microsoft.com/azure/active-directory/develop/v2-oauth2-client-creds-grant-flow).
* [Device code flow](https://docs.microsoft.com/azure/active-directory/develop/v2-oauth2-device-code).

License: MIT
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ async fn main() -> Result<(), Box<dyn Error>> {
let sub_id = AzureCliCredential::get_subscription().await?;
println!("Azure cli subscription: {sub_id}");

let credentials = AzureCliCredential::new();
let credentials = AzureCliCredential::new()?;
let res = credentials
.get_token(&["https://management.azure.com/.default"])
.await?;
Expand Down
Loading