From 07a70fbf8b09c7aebcd73ae1a0d1f8fc99661a0a Mon Sep 17 00:00:00 2001 From: Steven Yuan Date: Wed, 9 Aug 2023 13:53:55 -0700 Subject: [PATCH] feat(experimentalIdentityAndAuth): add `experimentalIdentityAndAuth` flag (#5065) As part of feature development of `experimentalIdentityAndAuth`, add control branches for existing behavior in existing integrations, particularly `@aws.auth#sigv4` and `@httpBearerTokenAuth`: - `AddAwsAuthPlugin` - `AddAwsRuntimeConfig` - `AddBuiltinPlugins` - `AddEventBridgePlugin` - `AddS3Config` - `AddS3ControlDependency` - `AddTokenAuthPlugin` - `AddEventStreamHandlingDependency` Also, add a section in `CONTRIBUTING.md` about experimental features in `smithy-typescript` used in `aws-sdk-js-v3`. --- CONTRIBUTING.md | 11 ++++++++ .../typescript/codegen/AddAwsAuthPlugin.java | 27 ++++++++++++++++--- .../codegen/AddAwsRuntimeConfig.java | 8 ++++++ .../typescript/codegen/AddBuiltinPlugins.java | 1 + .../codegen/AddEventBridgePlugin.java | 4 +++ .../AddEventStreamHandlingDependency.java | 10 +++++++ .../aws/typescript/codegen/AddS3Config.java | 8 ++++++ .../codegen/AddS3ControlDependency.java | 4 +++ .../codegen/AddTokenAuthPlugin.java | 2 ++ 9 files changed, 71 insertions(+), 4 deletions(-) diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index 2f0a06bd10e1..62ff70778d02 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -142,6 +142,17 @@ smithy=/Volumes/workplace/smithy smithy-typescript=/Volumes/workplace/smithy-typescript ``` +## Experimental Features + +`aws-sdk-js-v3 ` uses `smithy-typescript` to generate code. `smithy-typescript` is under heavy development and has +experimental features that can affect `aws-sdk-js-v3`. These features are enabled via opt-in settings in `sdk-codegen`. +Note that any contributions related to these features MUST be reviewed carefully for opt-in behavior via feature flags +as to not break any existing customers. Here are the experimental features that are currently under development: + +| Experimental Feature | Flag | Description | +| -------------------- | ----------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | +| Identity & Auth | `experimentalIdentityAndAuth` | Standardize identity and auth integrations to match the Smithy specification (see [Authentication Traits](https://smithy.io/2.0/spec/authentication-traits.html)). Newer capabilities include support for multiple auth schemes, `@optionalAuth`, and standardized identity interfaces for authentication schemes both in code generation and TypeScript packages. In `smithy-typescript`, `@httpApiKeyAuth` will be updated to use the new standardized interfaces. In `aws-sdk-js-v3` (`smithy-typescript`'s largest customer), this will affect `@aws.auth#sigv4` and `@httpBearerAuth` implementations, but is planned to be completely backwards-compatible. | + ## Build caching Build caching is optionally available via Turborepo. See `turbo.json`. diff --git a/codegen/smithy-aws-typescript-codegen/src/main/java/software/amazon/smithy/aws/typescript/codegen/AddAwsAuthPlugin.java b/codegen/smithy-aws-typescript-codegen/src/main/java/software/amazon/smithy/aws/typescript/codegen/AddAwsAuthPlugin.java index 4b57658fceb1..c60ec9671336 100644 --- a/codegen/smithy-aws-typescript-codegen/src/main/java/software/amazon/smithy/aws/typescript/codegen/AddAwsAuthPlugin.java +++ b/codegen/smithy-aws-typescript-codegen/src/main/java/software/amazon/smithy/aws/typescript/codegen/AddAwsAuthPlugin.java @@ -72,6 +72,10 @@ public void addConfigInterfaceFields( SymbolProvider symbolProvider, TypeScriptWriter writer ) { + if (settings.getExperimentalIdentityAndAuth()) { + return; + } + // feat(experimentalIdentityAndAuth): control branch for @aws.auth#sigv4 ServiceShape service = settings.getService(model); if (!isSigV4Service(service) && isAwsService(service)) { ServiceTrait serviceTrait = service.getTrait(ServiceTrait.class).get(); @@ -120,12 +124,14 @@ public List getClientPlugins() { && isAwsService(s) && !testServiceId(s, "STS") && !areAllOptionalAuthOperations(m, s)) + .settingsPredicate((m, s, settings) -> !settings.getExperimentalIdentityAndAuth()) .build(), RuntimeClientPlugin.builder() .withConventions(AwsDependency.MIDDLEWARE_SIGNING.dependency, "SigV4Auth", HAS_CONFIG) .servicePredicate((m, s) -> isSigV4Service(s) && !isAwsService(s) && !areAllOptionalAuthOperations(m, s)) + .settingsPredicate((m, s, settings) -> !settings.getExperimentalIdentityAndAuth()) .build(), RuntimeClientPlugin.builder() .withConventions(AwsDependency.STS_MIDDLEWARE.dependency, @@ -134,6 +140,7 @@ && isAwsService(s) put("stsClientCtor", Symbol.builder().name("STSClient").build()); }}) .servicePredicate((m, s) -> testServiceId(s, "STS")) + .settingsPredicate((m, s, settings) -> !settings.getExperimentalIdentityAndAuth()) .build(), RuntimeClientPlugin.builder() .withConventions(AwsDependency.MIDDLEWARE_SIGNING.dependency, "AwsAuth", HAS_MIDDLEWARE) @@ -141,26 +148,30 @@ && isAwsService(s) .servicePredicate((m, s) -> isSigV4Service(s) && isAwsService(s) && !testServiceId(s, "STS") - && !hasOptionalAuthOperation(m, s) - ).build(), + && !hasOptionalAuthOperation(m, s)) + .settingsPredicate((m, s, settings) -> !settings.getExperimentalIdentityAndAuth()) + .build(), RuntimeClientPlugin.builder() .withConventions(AwsDependency.MIDDLEWARE_SIGNING.dependency, "SigV4Auth", HAS_MIDDLEWARE) // See operationUsesAwsAuth() below for AwsAuth Middleware customizations. .servicePredicate((m, s) -> isSigV4Service(s) && !isAwsService(s) - && !hasOptionalAuthOperation(m, s) - ).build(), + && !hasOptionalAuthOperation(m, s)) + .settingsPredicate((m, s, settings) -> !settings.getExperimentalIdentityAndAuth()) + .build(), RuntimeClientPlugin.builder() .withConventions(AwsDependency.MIDDLEWARE_SIGNING.dependency, "AwsAuth", HAS_MIDDLEWARE) .operationPredicate((m, s, o) -> isSigV4Service(s) && isAwsService(s) && operationUsesAwsAuth(m, s, o)) + .settingsPredicate((m, s, settings) -> !settings.getExperimentalIdentityAndAuth()) .build(), RuntimeClientPlugin.builder() .withConventions(AwsDependency.MIDDLEWARE_SIGNING.dependency, "SigV4Auth", HAS_MIDDLEWARE) .operationPredicate((m, s, o) -> isSigV4Service(s) && !isAwsService(s) && operationUsesAwsAuth(m, s, o)) + .settingsPredicate((m, s, settings) -> !settings.getExperimentalIdentityAndAuth()) .build() ); @@ -173,6 +184,10 @@ public Map> getRuntimeConfigWriters( SymbolProvider symbolProvider, LanguageTarget target ) { + if (settings.getExperimentalIdentityAndAuth()) { + return Collections.emptyMap(); + } + // feat(experimentalIdentityAndAuth): control branch for @aws.auth#sigv4 ServiceShape service = settings.getService(model); if (!isSigV4Service(service) || areAllOptionalAuthOperations(model, service)) { return Collections.emptyMap(); @@ -219,6 +234,10 @@ public Map> getRuntimeConfigWriters( @Override public void customize(TypeScriptCodegenContext codegenContext) { + if (codegenContext.settings().getExperimentalIdentityAndAuth()) { + return; + } + // feat(experimentalIdentityAndAuth): control branch for @aws.auth#sigv4 TypeScriptSettings settings = codegenContext.settings(); Model model = codegenContext.model(); BiConsumer> writerFactory = codegenContext.writerDelegator()::useFileWriter; diff --git a/codegen/smithy-aws-typescript-codegen/src/main/java/software/amazon/smithy/aws/typescript/codegen/AddAwsRuntimeConfig.java b/codegen/smithy-aws-typescript-codegen/src/main/java/software/amazon/smithy/aws/typescript/codegen/AddAwsRuntimeConfig.java index 4f6ca01beda4..00919b963879 100644 --- a/codegen/smithy-aws-typescript-codegen/src/main/java/software/amazon/smithy/aws/typescript/codegen/AddAwsRuntimeConfig.java +++ b/codegen/smithy-aws-typescript-codegen/src/main/java/software/amazon/smithy/aws/typescript/codegen/AddAwsRuntimeConfig.java @@ -91,6 +91,10 @@ public void addConfigInterfaceFields( writer.writeDocs("Enables FIPS compatible endpoints.") .write("useFipsEndpoint?: boolean | __Provider;\n"); } + if (settings.getExperimentalIdentityAndAuth()) { + return; + } + // feat(experimentalIdentityAndAuth): control branch for AWS config interface fields if (isSigV4Service(settings, model)) { writer.writeDocs(isAwsService(settings, model) ? "The AWS region to which this client will send requests" @@ -134,6 +138,10 @@ private Map> getDefaultConfig( if (!isSigV4Service(settings, model)) { return Collections.emptyMap(); } + if (settings.getExperimentalIdentityAndAuth()) { + return Collections.emptyMap(); + } + // feat(experimentalIdentityAndAuth): control branch for AWS runtime config switch (target) { case BROWSER: return MapUtils.of("region", writer -> { diff --git a/codegen/smithy-aws-typescript-codegen/src/main/java/software/amazon/smithy/aws/typescript/codegen/AddBuiltinPlugins.java b/codegen/smithy-aws-typescript-codegen/src/main/java/software/amazon/smithy/aws/typescript/codegen/AddBuiltinPlugins.java index a9671af5ba0f..78455a23f5c4 100644 --- a/codegen/smithy-aws-typescript-codegen/src/main/java/software/amazon/smithy/aws/typescript/codegen/AddBuiltinPlugins.java +++ b/codegen/smithy-aws-typescript-codegen/src/main/java/software/amazon/smithy/aws/typescript/codegen/AddBuiltinPlugins.java @@ -50,6 +50,7 @@ public List getClientPlugins() { RuntimeClientPlugin.builder() .withConventions(TypeScriptDependency.CONFIG_RESOLVER.dependency, "Region", HAS_CONFIG) .servicePredicate((m, s) -> isAwsService(s) || isSigV4Service(s)) + .settingsPredicate((m, s, settings) -> !settings.getExperimentalIdentityAndAuth()) .build(), // Only one of Endpoints or CustomEndpoints should be used RuntimeClientPlugin.builder() diff --git a/codegen/smithy-aws-typescript-codegen/src/main/java/software/amazon/smithy/aws/typescript/codegen/AddEventBridgePlugin.java b/codegen/smithy-aws-typescript-codegen/src/main/java/software/amazon/smithy/aws/typescript/codegen/AddEventBridgePlugin.java index 35a96ab07d2d..970ac1829b8a 100644 --- a/codegen/smithy-aws-typescript-codegen/src/main/java/software/amazon/smithy/aws/typescript/codegen/AddEventBridgePlugin.java +++ b/codegen/smithy-aws-typescript-codegen/src/main/java/software/amazon/smithy/aws/typescript/codegen/AddEventBridgePlugin.java @@ -39,6 +39,10 @@ public Map> getRuntimeConfigWriters(TypeScrip if (!testServiceId(settings.getService(model))) { return Collections.emptyMap(); } + if (settings.getExperimentalIdentityAndAuth()) { + return Collections.emptyMap(); + } + // feat(experimentalIdentityAndAuth): control branch for EventBridge runtime config switch (target) { case SHARED: return MapUtils.of("signerConstructor", writer -> { diff --git a/codegen/smithy-aws-typescript-codegen/src/main/java/software/amazon/smithy/aws/typescript/codegen/AddEventStreamHandlingDependency.java b/codegen/smithy-aws-typescript-codegen/src/main/java/software/amazon/smithy/aws/typescript/codegen/AddEventStreamHandlingDependency.java index da6005f79d7b..fd9f1849d4d7 100644 --- a/codegen/smithy-aws-typescript-codegen/src/main/java/software/amazon/smithy/aws/typescript/codegen/AddEventStreamHandlingDependency.java +++ b/codegen/smithy-aws-typescript-codegen/src/main/java/software/amazon/smithy/aws/typescript/codegen/AddEventStreamHandlingDependency.java @@ -52,11 +52,13 @@ public List getClientPlugins() { .withConventions(AwsDependency.MIDDLEWARE_EVENTSTREAM.dependency, "EventStream", HAS_CONFIG) .servicePredicate(AddEventStreamHandlingDependency::hasEventStreamInput) + .settingsPredicate((m, s, settings) -> !settings.getExperimentalIdentityAndAuth()) .build(), RuntimeClientPlugin.builder() .withConventions(AwsDependency.MIDDLEWARE_EVENTSTREAM.dependency, "EventStream", HAS_MIDDLEWARE) .operationPredicate(AddEventStreamHandlingDependency::hasEventStreamInput) + .settingsPredicate((m, s, settings) -> !settings.getExperimentalIdentityAndAuth()) .build() ); } @@ -68,6 +70,10 @@ public void addConfigInterfaceFields( SymbolProvider symbolProvider, TypeScriptWriter writer ) { + if (settings.getExperimentalIdentityAndAuth()) { + return; + } + // feat(experimentalIdentityAndAuth): control branch for event stream handler interface fields if (hasEventStreamInput(model, settings.getService(model))) { writer.addImport("EventStreamPayloadHandlerProvider", "__EventStreamPayloadHandlerProvider", TypeScriptDependency.AWS_SDK_TYPES); @@ -89,6 +95,10 @@ public Map> getRuntimeConfigWriters( return Collections.emptyMap(); } + if (settings.getExperimentalIdentityAndAuth()) { + return Collections.emptyMap(); + } + // feat(experimentalIdentityAndAuth): control branch for event stream handler runtime config switch (target) { case NODE: return MapUtils.of("eventStreamPayloadHandlerProvider", writer -> { diff --git a/codegen/smithy-aws-typescript-codegen/src/main/java/software/amazon/smithy/aws/typescript/codegen/AddS3Config.java b/codegen/smithy-aws-typescript-codegen/src/main/java/software/amazon/smithy/aws/typescript/codegen/AddS3Config.java index c358d1e06978..4d86227d61c6 100644 --- a/codegen/smithy-aws-typescript-codegen/src/main/java/software/amazon/smithy/aws/typescript/codegen/AddS3Config.java +++ b/codegen/smithy-aws-typescript-codegen/src/main/java/software/amazon/smithy/aws/typescript/codegen/AddS3Config.java @@ -117,6 +117,10 @@ public void addConfigInterfaceFields( if (!isS3(service)) { return; } + if (settings.getExperimentalIdentityAndAuth()) { + return; + } + // feat(experimentalIdentityAndAuth): control branch for S3 Config interface fields writer.writeDocs("Whether to escape request path when signing the request.") .write("signingEscapePath?: boolean;\n"); writer.writeDocs( @@ -134,6 +138,10 @@ public Map> getRuntimeConfigWriters( if (!isS3(settings.getService(model))) { return Collections.emptyMap(); } + if (settings.getExperimentalIdentityAndAuth()) { + return Collections.emptyMap(); + } + // feat(experimentalIdentityAndAuth): control branch for S3 Config runtime config switch (target) { case SHARED: return MapUtils.of("signingEscapePath", writer -> { diff --git a/codegen/smithy-aws-typescript-codegen/src/main/java/software/amazon/smithy/aws/typescript/codegen/AddS3ControlDependency.java b/codegen/smithy-aws-typescript-codegen/src/main/java/software/amazon/smithy/aws/typescript/codegen/AddS3ControlDependency.java index dc15730c5bcb..498c317f86d8 100644 --- a/codegen/smithy-aws-typescript-codegen/src/main/java/software/amazon/smithy/aws/typescript/codegen/AddS3ControlDependency.java +++ b/codegen/smithy-aws-typescript-codegen/src/main/java/software/amazon/smithy/aws/typescript/codegen/AddS3ControlDependency.java @@ -101,6 +101,10 @@ public Map> getRuntimeConfigWriters( if (!isS3Control(settings.getService(model))) { return Collections.emptyMap(); } + if (settings.getExperimentalIdentityAndAuth()) { + return Collections.emptyMap(); + } + // feat(experimentalIdentityAndAuth): control branch for S3 Control signingEscapePath switch (target) { case SHARED: return MapUtils.of("signingEscapePath", writer -> { diff --git a/codegen/smithy-aws-typescript-codegen/src/main/java/software/amazon/smithy/aws/typescript/codegen/AddTokenAuthPlugin.java b/codegen/smithy-aws-typescript-codegen/src/main/java/software/amazon/smithy/aws/typescript/codegen/AddTokenAuthPlugin.java index 64d158d83983..c82d8c9703ba 100644 --- a/codegen/smithy-aws-typescript-codegen/src/main/java/software/amazon/smithy/aws/typescript/codegen/AddTokenAuthPlugin.java +++ b/codegen/smithy-aws-typescript-codegen/src/main/java/software/amazon/smithy/aws/typescript/codegen/AddTokenAuthPlugin.java @@ -36,10 +36,12 @@ public List getClientPlugins() { RuntimeClientPlugin.builder() .withConventions(AwsDependency.MIDDLEWARE_TOKEN.dependency, "Token", HAS_CONFIG) .servicePredicate((m, s) -> isHttpBearerAuthService(s)) + .settingsPredicate((m, s, settings) -> !settings.getExperimentalIdentityAndAuth()) .build(), RuntimeClientPlugin.builder() .withConventions(AwsDependency.MIDDLEWARE_TOKEN.dependency, "Token", HAS_MIDDLEWARE) .servicePredicate((m, s) -> isHttpBearerAuthService(s)) + .settingsPredicate((m, s, settings) -> !settings.getExperimentalIdentityAndAuth()) .build() ); }