From b6ab4ea81d131d171004dc204d39bb3ba2449849 Mon Sep 17 00:00:00 2001 From: Zelda Hessler Date: Fri, 2 Dec 2022 14:28:57 -0600 Subject: [PATCH] Fix inability to create service clients when `default-features = false` (#2055) * add: tests for config/client construction when default features are disabled fix: enable users to create service clients when default features are disabled update: missing HTTP connector panic messages * Apply suggestions from code review Co-authored-by: John DiSanti --- aws/rust-runtime/aws-config/src/connector.rs | 2 +- .../rustsdk/AwsFluentClientDecorator.kt | 30 ++++++++++++++++--- aws/sdk/integration-tests/Cargo.toml | 1 + .../no-default-features/Cargo.toml | 19 ++++++++++++ .../tests/client-construction.rs | 24 +++++++++++++++ 5 files changed, 71 insertions(+), 5 deletions(-) create mode 100644 aws/sdk/integration-tests/no-default-features/Cargo.toml create mode 100644 aws/sdk/integration-tests/no-default-features/tests/client-construction.rs diff --git a/aws/rust-runtime/aws-config/src/connector.rs b/aws/rust-runtime/aws-config/src/connector.rs index 4ea5ee77ff..e023695363 100644 --- a/aws/rust-runtime/aws-config/src/connector.rs +++ b/aws/rust-runtime/aws-config/src/connector.rs @@ -13,7 +13,7 @@ use std::sync::Arc; // unused when all crate features are disabled /// Unwrap an [`Option`](aws_smithy_client::erase::DynConnector), and panic with a helpful error message if it's `None` pub(crate) fn expect_connector(connector: Option) -> DynConnector { - connector.expect("A connector was not available. Either set a custom connector or enable the `rustls` and `native-tls` crate features.") + connector.expect("No HTTP connector was available. Enable the `rustls` or `native-tls` crate feature or set a connector to fix this.") } #[cfg(any(feature = "rustls", feature = "native-tls"))] diff --git a/aws/sdk-codegen/src/main/kotlin/software/amazon/smithy/rustsdk/AwsFluentClientDecorator.kt b/aws/sdk-codegen/src/main/kotlin/software/amazon/smithy/rustsdk/AwsFluentClientDecorator.kt index 2ec1b5e290..9841647fdf 100644 --- a/aws/sdk-codegen/src/main/kotlin/software/amazon/smithy/rustsdk/AwsFluentClientDecorator.kt +++ b/aws/sdk-codegen/src/main/kotlin/software/amazon/smithy/rustsdk/AwsFluentClientDecorator.kt @@ -158,13 +158,25 @@ private class AwsFluentClientExtensions(types: Types) { rustTemplate( """ /// Creates a new client from an [SDK Config](#{aws_types}::sdk_config::SdkConfig). - ##[cfg(any(feature = "rustls", feature = "native-tls"))] + /// + /// ## Panics + /// + /// - This method will panic if the `sdk_config` is missing an async sleep implementation. If you experience this panic, set + /// the `sleep_impl` on the Config passed into this function to fix it. + /// - This method will panic if the `sdk_config` is missing an HTTP connector. If you experience this panic, set the + /// `http_connector` on the Config passed into this function to fix it. pub fn new(sdk_config: &#{aws_types}::sdk_config::SdkConfig) -> Self { Self::from_conf(sdk_config.into()) } /// Creates a new client from the service [`Config`](crate::Config). - ##[cfg(any(feature = "rustls", feature = "native-tls"))] + /// + /// ## Panics + /// + /// - This method will panic if the `conf` is missing an async sleep implementation. If you experience this panic, set + /// the `sleep_impl` on the Config passed into this function to fix it. + /// - This method will panic if the `conf` is missing an HTTP connector. If you experience this panic, set the + /// `http_connector` on the Config passed into this function to fix it. pub fn from_conf(conf: crate::Config) -> Self { let retry_config = conf.retry_config().cloned().unwrap_or_else(#{RetryConfig}::disabled); let timeout_config = conf.timeout_config().cloned().unwrap_or_else(#{TimeoutConfig}::disabled); @@ -186,11 +198,21 @@ private class AwsFluentClientExtensions(types: Types) { }); let builder = #{aws_smithy_client}::Builder::new(); + let builder = match connector { // Use provided connector Some(c) => builder.connector(c), - // Use default connector based on enabled features - None => builder.dyn_https_connector(#{ConnectorSettings}::from_timeout_config(&timeout_config)), + None =>{ + ##[cfg(any(feature = "rustls", feature = "native-tls"))] + { + // Use default connector based on enabled features + builder.dyn_https_connector(#{ConnectorSettings}::from_timeout_config(&timeout_config)) + } + ##[cfg(not(any(feature = "rustls", feature = "native-tls")))] + { + panic!("No HTTP connector was available. Enable the `rustls` or `native-tls` crate feature or set a connector to fix this."); + } + } }; let mut builder = builder .middleware(#{DynMiddleware}::new(#{Middleware}::new())) diff --git a/aws/sdk/integration-tests/Cargo.toml b/aws/sdk/integration-tests/Cargo.toml index 0378cd24fb..406b718a94 100644 --- a/aws/sdk/integration-tests/Cargo.toml +++ b/aws/sdk/integration-tests/Cargo.toml @@ -8,6 +8,7 @@ members = [ "iam", "kms", "lambda", + "no-default-features", "polly", "qldbsession", "s3", diff --git a/aws/sdk/integration-tests/no-default-features/Cargo.toml b/aws/sdk/integration-tests/no-default-features/Cargo.toml new file mode 100644 index 0000000000..45980e2b90 --- /dev/null +++ b/aws/sdk/integration-tests/no-default-features/Cargo.toml @@ -0,0 +1,19 @@ +# This Cargo.toml is unused in generated code. It exists solely to enable these tests to compile in-situ +[package] +name = "no-default-features" +version = "0.1.0" +authors = ["Zelda Hessler "] +description = """ +These tests ensure that things will fail (or not fail) as expected +when default features are disabled for all SDK and runtime crates. +""" +edition = "2021" + +# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html + +[dev-dependencies] +aws-config = { path = "../../build/aws-sdk/sdk/aws-config", default-features = false } +aws-sdk-s3 = { path = "../../build/aws-sdk/sdk/s3", default-features = false } +futures = "0.3.25" +tokio = { version = "1.8.4", features = ["full", "test-util"] } +tracing-subscriber = { version = "0.3.15", features = ["env-filter"] } diff --git a/aws/sdk/integration-tests/no-default-features/tests/client-construction.rs b/aws/sdk/integration-tests/no-default-features/tests/client-construction.rs new file mode 100644 index 0000000000..1a602dc985 --- /dev/null +++ b/aws/sdk/integration-tests/no-default-features/tests/client-construction.rs @@ -0,0 +1,24 @@ +/* + * Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. + * SPDX-License-Identifier: Apache-2.0 + */ + +// This will fail due to lack of a connector when constructing the SDK Config +#[tokio::test] +#[should_panic( + expected = "No HTTP connector was available. Enable the `rustls` or `native-tls` crate feature or set a connector to fix this." +)] +async fn test_clients_from_sdk_config() { + aws_config::load_from_env().await; +} + +// This will fail due to lack of a connector when constructing the service client +#[test] +#[should_panic( + expected = "No HTTP connector was available. Enable the `rustls` or `native-tls` crate feature or set a connector to fix this." +)] +fn test_clients_from_service_config() { + let config = aws_sdk_s3::Config::builder().build(); + // This will panic due to the lack of an HTTP connector + aws_sdk_s3::Client::from_conf(config); +}