From bab8e2303e7ade916e121b7a09de7319be35c362 Mon Sep 17 00:00:00 2001 From: Russell Cohen Date: Fri, 27 Aug 2021 16:19:16 -0400 Subject: [PATCH] Add a minimal implementation of shared config (#673) * Add a minimal implementation of shared config * update changelog --- CHANGELOG.md | 1 + aws/rust-runtime/aws-types/src/config.rs | 78 +++++++++++++++++++ aws/rust-runtime/aws-types/src/lib.rs | 1 + .../smithy/rustsdk/AwsCodegenDecorator.kt | 1 + .../smithy/rustsdk/SharedConfigDecorator.kt | 78 +++++++++++++++++++ aws/sdk/integration-tests/dynamodb/Cargo.toml | 1 + .../dynamodb/tests/shared-config.rs | 25 ++++++ 7 files changed, 185 insertions(+) create mode 100644 aws/rust-runtime/aws-types/src/config.rs create mode 100644 aws/sdk-codegen/src/main/kotlin/software/amazon/smithy/rustsdk/SharedConfigDecorator.kt create mode 100644 aws/sdk/integration-tests/dynamodb/tests/shared-config.rs diff --git a/CHANGELOG.md b/CHANGELOG.md index 750e64f46..0c571ce7b 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -12,6 +12,7 @@ vNext (Month Day, Year) - (When complete) Add profile file provider for region (#594, #xyz) - Improve documentation on collection-aware builders (#664) - Add support for Transcribe `StartStreamTranscription` and S3 `SelectObjectContent` operations (#667) +- Add support for shared configuration between multiple services (#673) **Internal Changes** - Add NowOrLater future to smithy-async (#672) diff --git a/aws/rust-runtime/aws-types/src/config.rs b/aws/rust-runtime/aws-types/src/config.rs new file mode 100644 index 000000000..307a8ee7b --- /dev/null +++ b/aws/rust-runtime/aws-types/src/config.rs @@ -0,0 +1,78 @@ +/* + * Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. + * SPDX-License-Identifier: Apache-2.0. + */ + +#![deny(missing_docs)] + +//! AWS Shared Config +//! +//! This module contains an shared configuration representation that is agnostic from a specific service. + +use crate::region::Region; + +/// AWS Shared Configuration +pub struct Config { + region: Option, +} + +/// Builder for AWS Shared Configuration +#[derive(Default)] +pub struct Builder { + region: Option, +} + +impl Builder { + /// Set the region for the builder + /// + /// # Example + /// ```rust + /// use aws_types::config::Config; + /// use aws_types::region::Region; + /// let config = Config::builder().region(Region::new("us-east-1")).build(); + /// ``` + pub fn region(mut self, region: impl Into>) -> Self { + self.set_region(region); + self + } + + /// Set the region for the builder + /// + /// # Example + /// ```rust + /// fn region_override() -> Option { + /// // ... + /// # None + /// } + /// use aws_types::config::Config; + /// use aws_types::region::Region; + /// let mut builder = Config::builder(); + /// if let Some(region) = region_override() { + /// builder.set_region(region); + /// } + /// let config = builder.build(); + /// ``` + pub fn set_region(&mut self, region: impl Into>) -> &mut Self { + self.region = region.into(); + self + } + + /// Build a [`Config`](Config) from this builder + pub fn build(self) -> Config { + Config { + region: self.region, + } + } +} + +impl Config { + /// Configured region + pub fn region(&self) -> Option<&Region> { + self.region.as_ref() + } + + /// Config builder + pub fn builder() -> Builder { + Builder::default() + } +} diff --git a/aws/rust-runtime/aws-types/src/lib.rs b/aws/rust-runtime/aws-types/src/lib.rs index 5916d2fac..44f298b43 100644 --- a/aws/rust-runtime/aws-types/src/lib.rs +++ b/aws/rust-runtime/aws-types/src/lib.rs @@ -5,6 +5,7 @@ pub mod build_metadata; // internal APIs, may be unstable +pub mod config; #[doc(hidden)] pub mod os_shim_internal; pub mod profile; diff --git a/aws/sdk-codegen/src/main/kotlin/software/amazon/smithy/rustsdk/AwsCodegenDecorator.kt b/aws/sdk-codegen/src/main/kotlin/software/amazon/smithy/rustsdk/AwsCodegenDecorator.kt index a97fd8d3f..ba5778157 100644 --- a/aws/sdk-codegen/src/main/kotlin/software/amazon/smithy/rustsdk/AwsCodegenDecorator.kt +++ b/aws/sdk-codegen/src/main/kotlin/software/amazon/smithy/rustsdk/AwsCodegenDecorator.kt @@ -22,6 +22,7 @@ val DECORATORS = listOf( IntegrationTestDecorator(), AwsFluentClientDecorator(), CrateLicenseDecorator(), + SharedConfigDecorator(), // Service specific decorators DisabledAuthDecorator(), diff --git a/aws/sdk-codegen/src/main/kotlin/software/amazon/smithy/rustsdk/SharedConfigDecorator.kt b/aws/sdk-codegen/src/main/kotlin/software/amazon/smithy/rustsdk/SharedConfigDecorator.kt new file mode 100644 index 000000000..bc085be05 --- /dev/null +++ b/aws/sdk-codegen/src/main/kotlin/software/amazon/smithy/rustsdk/SharedConfigDecorator.kt @@ -0,0 +1,78 @@ +/* + * Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. + * SPDX-License-Identifier: Apache-2.0. + */ + +package software.amazon.smithy.rustsdk + +import software.amazon.smithy.rust.codegen.rustlang.RustModule +import software.amazon.smithy.rust.codegen.rustlang.Writable +import software.amazon.smithy.rust.codegen.rustlang.asType +import software.amazon.smithy.rust.codegen.rustlang.rustTemplate +import software.amazon.smithy.rust.codegen.rustlang.writable +import software.amazon.smithy.rust.codegen.smithy.RuntimeConfig +import software.amazon.smithy.rust.codegen.smithy.RustCrate +import software.amazon.smithy.rust.codegen.smithy.customize.RustCodegenDecorator +import software.amazon.smithy.rust.codegen.smithy.generators.ProtocolConfig +import software.amazon.smithy.rust.codegen.smithy.generators.config.ConfigCustomization +import software.amazon.smithy.rust.codegen.smithy.generators.config.ServiceConfig + +/** + * Adds functionality for constructing ::Config objects from aws_types::Config (SharedConfig) + * + * - `From<&aws_types::Config> for ::config::Builder`: Enabling customization + * - `pub fn new(&aws_types::Config) -> ::Config`: Direct construction without customization + */ +class SharedConfigDecorator : RustCodegenDecorator { + override val name: String = "SharedConfig" + override val order: Byte = 0 + + override fun configCustomizations( + protocolConfig: ProtocolConfig, + baseCustomizations: List + ): List { + return baseCustomizations + NewFromShared(protocolConfig.runtimeConfig) + } + + override fun extras(protocolConfig: ProtocolConfig, rustCrate: RustCrate) { + val codegenScope = arrayOf( + "Config" to awsTypes(runtimeConfig = protocolConfig.runtimeConfig).asType().member("config::Config") + ) + rustCrate.withModule(RustModule.Config) { + // TODO(sharedconfig): As more items are added to aws_types::Config, use them here to configure the config builder + it.rustTemplate( + """ + impl From<&#{Config}> for Builder { + fn from(input: &#{Config}) -> Self { + let mut builder = Builder::default(); + builder = builder.region(input.region().cloned()); + builder + } + } + """, + *codegenScope + ) + } + } +} + +class NewFromShared(runtimeConfig: RuntimeConfig) : ConfigCustomization() { + private val codegenScope = arrayOf( + "Config" to awsTypes(runtimeConfig = runtimeConfig).asType().member("config::Config") + ) + override fun section(section: ServiceConfig): Writable { + return when (section) { + ServiceConfig.ConfigImpl -> writable { + rustTemplate( + """ + pub fn new(config: &#{Config}) -> Self { + Builder::from(config).build() + } + """, + *codegenScope + ) + } + else -> emptySection + } + } +} diff --git a/aws/sdk/integration-tests/dynamodb/Cargo.toml b/aws/sdk/integration-tests/dynamodb/Cargo.toml index 8be40e6b4..b99f9ca9b 100644 --- a/aws/sdk/integration-tests/dynamodb/Cargo.toml +++ b/aws/sdk/integration-tests/dynamodb/Cargo.toml @@ -11,6 +11,7 @@ edition = "2018" aws-auth = { path = "../../build/aws-sdk/aws-auth" } aws-http = { path = "../../build/aws-sdk/aws-http" } aws-hyper = { path = "../../build/aws-sdk/aws-hyper" } +aws-types = { path = "../../build/aws-sdk/aws-types" } aws-sdk-dynamodb = { path = "../../build/aws-sdk/dynamodb" } bytes = "1" criterion = { version = "0.3.4" } diff --git a/aws/sdk/integration-tests/dynamodb/tests/shared-config.rs b/aws/sdk/integration-tests/dynamodb/tests/shared-config.rs new file mode 100644 index 000000000..512017c68 --- /dev/null +++ b/aws/sdk/integration-tests/dynamodb/tests/shared-config.rs @@ -0,0 +1,25 @@ +/* + * Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. + * SPDX-License-Identifier: Apache-2.0. + */ + +use aws_sdk_dynamodb::{Credentials, Region}; +use http::Uri; + +/// Iterative test of loading clients from shared configuration +#[tokio::test] +async fn shared_config_testbed() { + let shared_config = aws_types::config::Config::builder() + .region(Region::new("us-east-4")) + .build(); + let conf = aws_sdk_dynamodb::config::Builder::from(&shared_config) + .credentials_provider(Credentials::from_keys("asdf", "asdf", None)) + .build(); + let (conn, request) = smithy_client::test_connection::capture_request(None); + let svc = aws_sdk_dynamodb::Client::from_conf_conn(conf, conn); + let _ = svc.list_tables().send().await; + assert_eq!( + request.expect_request().uri(), + &Uri::from_static("https://dynamodb.us-east-4.amazonaws.com") + ); +} -- GitLab