From 6ab9802eea2bbe2b3aa1e7ec92144a006b8fe053 Mon Sep 17 00:00:00 2001 From: Saranya Somepalli Date: Wed, 13 May 2026 09:51:19 -0700 Subject: [PATCH 1/7] Preserve interceptor-set signer properties across auth scheme and endpoint resolution --- .../internal/AwsExecutionContextBuilder.java | 3 + .../core/http/auth/AuthSchemeResolver.java | 69 ++++++++++++++++++- .../SdkInternalExecutionAttribute.java | 17 +++++ .../stages/AuthSchemeResolutionStage.java | 3 + .../stages/EndpointResolutionStage.java | 21 ++++++ ...onAttributeBackwardsCompatibilityTest.java | 5 +- 6 files changed, 113 insertions(+), 5 deletions(-) diff --git a/core/aws-core/src/main/java/software/amazon/awssdk/awscore/internal/AwsExecutionContextBuilder.java b/core/aws-core/src/main/java/software/amazon/awssdk/awscore/internal/AwsExecutionContextBuilder.java index b3ce212efbee..b5772197f481 100644 --- a/core/aws-core/src/main/java/software/amazon/awssdk/awscore/internal/AwsExecutionContextBuilder.java +++ b/core/aws-core/src/main/java/software/amazon/awssdk/awscore/internal/AwsExecutionContextBuilder.java @@ -161,6 +161,9 @@ private AwsExecutionContextBuilder() { ExecutionInterceptorChain executionInterceptorChain = new ExecutionInterceptorChain(clientConfig.option(SdkClientOption.EXECUTION_INTERCEPTORS)); + executionAttributes.putAttribute(SdkInternalExecutionAttribute.AUTH_SCHEME_BEFORE_INTERCEPTORS, + executionAttributes.getAttribute(SdkInternalExecutionAttribute.SELECTED_AUTH_SCHEME)); + InterceptorContext interceptorContext = InterceptorContext.builder() .request(originalRequest) .asyncRequestBody(executionParams.getAsyncRequestBody()) diff --git a/core/sdk-core/src/main/java/software/amazon/awssdk/core/http/auth/AuthSchemeResolver.java b/core/sdk-core/src/main/java/software/amazon/awssdk/core/http/auth/AuthSchemeResolver.java index ea0d8d6db9b7..721184ea0fe5 100644 --- a/core/sdk-core/src/main/java/software/amazon/awssdk/core/http/auth/AuthSchemeResolver.java +++ b/core/sdk-core/src/main/java/software/amazon/awssdk/core/http/auth/AuthSchemeResolver.java @@ -19,6 +19,7 @@ import java.util.ArrayList; import java.util.List; import java.util.Map; +import java.util.Objects; import java.util.concurrent.CompletableFuture; import java.util.function.Supplier; import java.util.stream.Collectors; @@ -35,6 +36,7 @@ import software.amazon.awssdk.http.auth.spi.scheme.AuthScheme; import software.amazon.awssdk.http.auth.spi.scheme.AuthSchemeOption; import software.amazon.awssdk.http.auth.spi.signer.HttpSigner; +import software.amazon.awssdk.http.auth.spi.signer.SignerProperty; import software.amazon.awssdk.identity.spi.AwsCredentialsIdentity; import software.amazon.awssdk.identity.spi.Identity; import software.amazon.awssdk.identity.spi.IdentityProvider; @@ -137,9 +139,23 @@ public static SelectedAuthScheme mergePreExistingAuthSch return selectedAuthScheme; } + SelectedAuthScheme beforeInterceptors = + executionAttributes.getAttribute(SdkInternalExecutionAttribute.AUTH_SCHEME_BEFORE_INTERCEPTORS); + AuthSchemeOption.Builder mergedOption = selectedAuthScheme.authSchemeOption().toBuilder(); + + existingAuthScheme.authSchemeOption().forEachSignerProperty(new AuthSchemeOption.SignerPropertyConsumer() { + @Override + public void accept(SignerProperty key, S value) { + if (wasModifiedByInterceptor(beforeInterceptors, key, value)) { + mergedOption.putSignerProperty(key, value); + } else { + mergedOption.putSignerPropertyIfAbsent(key, value); + } + } + }); + existingAuthScheme.authSchemeOption().forEachIdentityProperty(mergedOption::putIdentityPropertyIfAbsent); - existingAuthScheme.authSchemeOption().forEachSignerProperty(mergedOption::putSignerPropertyIfAbsent); return new SelectedAuthScheme<>( selectedAuthScheme.identity(), @@ -148,6 +164,57 @@ public static SelectedAuthScheme mergePreExistingAuthSch ); } + private static boolean wasModifiedByInterceptor(SelectedAuthScheme beforeInterceptors, + SignerProperty key, T currentValue) { + if (beforeInterceptors == null) { + return true; + } + T originalValue = beforeInterceptors.authSchemeOption().signerProperty(key); + return !Objects.equals(originalValue, currentValue); + } + + /** + * Re-applies interceptor-modified signer properties onto the current auth scheme. + * Called after endpoint resolution, which may have overwritten properties that interceptors set. + */ + public static void applyInterceptorModifiedProperties(SelectedAuthScheme currentScheme, + SelectedAuthScheme beforeInterceptors, + SelectedAuthScheme afterInterceptors, + ExecutionAttributes attrs) { + if (afterInterceptors == null) { + return; + } + doApplyInterceptorModifiedProperties(currentScheme, beforeInterceptors, afterInterceptors, attrs); + } + + @SuppressWarnings("unchecked") + private static void doApplyInterceptorModifiedProperties( + SelectedAuthScheme currentScheme, + SelectedAuthScheme beforeInterceptors, + SelectedAuthScheme afterInterceptors, + ExecutionAttributes attrs) { + + AuthSchemeOption.Builder mergedOption = currentScheme.authSchemeOption().toBuilder(); + boolean[] changed = {false}; + + afterInterceptors.authSchemeOption().forEachSignerProperty(new AuthSchemeOption.SignerPropertyConsumer() { + @Override + public void accept(SignerProperty key, S value) { + if (wasModifiedByInterceptor(beforeInterceptors, key, value)) { + mergedOption.putSignerProperty(key, value); + changed[0] = true; + } + } + }); + + if (changed[0]) { + attrs.putAttribute(SdkInternalExecutionAttribute.SELECTED_AUTH_SCHEME, + new SelectedAuthScheme<>(currentScheme.identity(), + currentScheme.signer(), + mergedOption.build())); + } + } + private static SelectedAuthScheme trySelectAuthScheme( AuthSchemeOption authOption, AuthScheme authScheme, diff --git a/core/sdk-core/src/main/java/software/amazon/awssdk/core/interceptor/SdkInternalExecutionAttribute.java b/core/sdk-core/src/main/java/software/amazon/awssdk/core/interceptor/SdkInternalExecutionAttribute.java index 60254eb8e5c4..c83541d8d570 100644 --- a/core/sdk-core/src/main/java/software/amazon/awssdk/core/interceptor/SdkInternalExecutionAttribute.java +++ b/core/sdk-core/src/main/java/software/amazon/awssdk/core/interceptor/SdkInternalExecutionAttribute.java @@ -177,6 +177,7 @@ public final class SdkInternalExecutionAttribute extends SdkExecutionAttribute { public static final ExecutionAttribute IDENTITY_PROVIDER_UPDATER = new ExecutionAttribute<>("IdentityProviderUpdater"); + /** /** * Callback to resolve auth scheme options from the (possibly modified) request. * Called by AuthSchemeResolutionStage after interceptors have run. @@ -204,6 +205,22 @@ public final class SdkInternalExecutionAttribute extends SdkExecutionAttribute { public static final ExecutionAttribute> SELECTED_AUTH_SCHEME = new ExecutionAttribute<>("SelectedAuthScheme"); + /** + * Snapshot of {@link #SELECTED_AUTH_SCHEME} taken before execution interceptors run. + * Used by {@code AuthSchemeResolver#mergePreExistingAuthSchemeProperties} to detect which signer properties + * were explicitly modified by interceptors (and should therefore override the freshly-resolved values). + */ + public static final ExecutionAttribute> AUTH_SCHEME_BEFORE_INTERCEPTORS = + new ExecutionAttribute<>("AuthSchemeBeforeInterceptors"); + + /** + * Snapshot of {@link #SELECTED_AUTH_SCHEME} taken after interceptors run but before auth scheme resolution. + * Together with {@link #AUTH_SCHEME_BEFORE_INTERCEPTORS}, this allows detecting which signer properties + * were explicitly modified by interceptors so they can be re-applied after endpoint resolution. + */ + public static final ExecutionAttribute> AUTH_SCHEME_AFTER_INTERCEPTORS = + new ExecutionAttribute<>("AuthSchemeAfterInterceptors"); + /** * The supported compression algorithms for an operation, and whether the operation is streaming or not. */ diff --git a/core/sdk-core/src/main/java/software/amazon/awssdk/core/internal/http/pipeline/stages/AuthSchemeResolutionStage.java b/core/sdk-core/src/main/java/software/amazon/awssdk/core/internal/http/pipeline/stages/AuthSchemeResolutionStage.java index ebc42009ce7c..35acd7bf8aaf 100644 --- a/core/sdk-core/src/main/java/software/amazon/awssdk/core/internal/http/pipeline/stages/AuthSchemeResolutionStage.java +++ b/core/sdk-core/src/main/java/software/amazon/awssdk/core/internal/http/pipeline/stages/AuthSchemeResolutionStage.java @@ -76,6 +76,9 @@ public SdkHttpFullRequest.Builder execute(SdkHttpFullRequest.Builder request, Re SelectedAuthScheme selectedAuthScheme = AuthSchemeResolver.selectAuthScheme(authOptions, authSchemes, identityProviders, metricCollector); + executionAttributes.putAttribute(SdkInternalExecutionAttribute.AUTH_SCHEME_AFTER_INTERCEPTORS, + executionAttributes.getAttribute(SdkInternalExecutionAttribute.SELECTED_AUTH_SCHEME)); + selectedAuthScheme = AuthSchemeResolver.mergePreExistingAuthSchemeProperties(selectedAuthScheme, executionAttributes); executionAttributes.putAttribute(SdkInternalExecutionAttribute.SELECTED_AUTH_SCHEME, selectedAuthScheme); diff --git a/core/sdk-core/src/main/java/software/amazon/awssdk/core/internal/http/pipeline/stages/EndpointResolutionStage.java b/core/sdk-core/src/main/java/software/amazon/awssdk/core/internal/http/pipeline/stages/EndpointResolutionStage.java index b01dc444fa77..e183f3ab16ce 100644 --- a/core/sdk-core/src/main/java/software/amazon/awssdk/core/internal/http/pipeline/stages/EndpointResolutionStage.java +++ b/core/sdk-core/src/main/java/software/amazon/awssdk/core/internal/http/pipeline/stages/EndpointResolutionStage.java @@ -22,6 +22,8 @@ import software.amazon.awssdk.annotations.SdkInternalApi; import software.amazon.awssdk.core.ClientEndpointProvider; import software.amazon.awssdk.core.SdkRequest; +import software.amazon.awssdk.core.SelectedAuthScheme; +import software.amazon.awssdk.core.http.auth.AuthSchemeResolver; import software.amazon.awssdk.core.interceptor.ExecutionAttributes; import software.amazon.awssdk.core.interceptor.SdkExecutionAttribute; import software.amazon.awssdk.core.interceptor.SdkInternalExecutionAttribute; @@ -70,6 +72,8 @@ public SdkHttpFullRequest.Builder execute(SdkHttpFullRequest.Builder request, Re Endpoint endpoint = resolver.resolve(sdkRequest, attrs); Duration resolveEndpointDuration = Duration.ofNanos(System.nanoTime() - resolveEndpointStart); + reapplyInterceptorModifiedAuthProperties(attrs); + MetricCollector metricCollector = attrs.getAttribute(SdkExecutionAttribute.API_CALL_METRIC_COLLECTOR); if (metricCollector != null) { metricCollector.reportMetric(CoreMetric.ENDPOINT_RESOLVE_DURATION, resolveEndpointDuration); @@ -140,4 +144,21 @@ private static String combinePath(String clientEndpointPath, String requestPath, String requestPathWithClientPathRemoved = StringUtils.replaceOnce(requestPath, clientEndpointPath, ""); return SdkHttpUtils.appendUri(resolvedUriPath, requestPathWithClientPathRemoved); } + + private static void reapplyInterceptorModifiedAuthProperties(ExecutionAttributes attrs) { + SelectedAuthScheme currentScheme = attrs.getAttribute(SdkInternalExecutionAttribute.SELECTED_AUTH_SCHEME); + if (currentScheme == null) { + return; + } + SelectedAuthScheme beforeInterceptors = + attrs.getAttribute(SdkInternalExecutionAttribute.AUTH_SCHEME_BEFORE_INTERCEPTORS); + + SelectedAuthScheme afterInterceptors = + attrs.getAttribute(SdkInternalExecutionAttribute.AUTH_SCHEME_AFTER_INTERCEPTORS); + if (afterInterceptors == null) { + return; + } + + AuthSchemeResolver.applyInterceptorModifiedProperties(currentScheme, beforeInterceptors, afterInterceptors, attrs); + } } diff --git a/services/s3/src/test/java/software/amazon/awssdk/services/s3/ExecutionAttributeBackwardsCompatibilityTest.java b/services/s3/src/test/java/software/amazon/awssdk/services/s3/ExecutionAttributeBackwardsCompatibilityTest.java index a4816d22e4d0..22b8c7f4efae 100644 --- a/services/s3/src/test/java/software/amazon/awssdk/services/s3/ExecutionAttributeBackwardsCompatibilityTest.java +++ b/services/s3/src/test/java/software/amazon/awssdk/services/s3/ExecutionAttributeBackwardsCompatibilityTest.java @@ -72,10 +72,7 @@ public void canSetSignerExecutionAttributes_beforeExecution() { public void beforeExecution(Context.BeforeExecution context, ExecutionAttributes executionAttributes) { attributeModifications.accept(executionAttributes); } - }, - AwsSignerExecutionAttribute.SERVICE_SIGNING_NAME, // Endpoint rules override signing name - AwsSignerExecutionAttribute.SIGNING_REGION, // Endpoint rules override signing region - AwsSignerExecutionAttribute.SIGNER_DOUBLE_URL_ENCODE); // Endpoint rules override double-url-encode + }); } @Test From bd27de136100e07592b2f26a6d396d87d490b207 Mon Sep 17 00:00:00 2001 From: Saranya Somepalli Date: Thu, 14 May 2026 09:56:00 -0700 Subject: [PATCH 2/7] Address PR feedback --- .../amazon/awssdk/core/http/auth/AuthSchemeResolver.java | 5 +++++ .../core/interceptor/SdkInternalExecutionAttribute.java | 1 - 2 files changed, 5 insertions(+), 1 deletion(-) diff --git a/core/sdk-core/src/main/java/software/amazon/awssdk/core/http/auth/AuthSchemeResolver.java b/core/sdk-core/src/main/java/software/amazon/awssdk/core/http/auth/AuthSchemeResolver.java index 721184ea0fe5..01c4e96e333a 100644 --- a/core/sdk-core/src/main/java/software/amazon/awssdk/core/http/auth/AuthSchemeResolver.java +++ b/core/sdk-core/src/main/java/software/amazon/awssdk/core/http/auth/AuthSchemeResolver.java @@ -142,6 +142,11 @@ public static SelectedAuthScheme mergePreExistingAuthSch SelectedAuthScheme beforeInterceptors = executionAttributes.getAttribute(SdkInternalExecutionAttribute.AUTH_SCHEME_BEFORE_INTERCEPTORS); + if (beforeInterceptors != null && + beforeInterceptors.authSchemeOption() == existingAuthScheme.authSchemeOption()) { + return selectedAuthScheme; + } + AuthSchemeOption.Builder mergedOption = selectedAuthScheme.authSchemeOption().toBuilder(); existingAuthScheme.authSchemeOption().forEachSignerProperty(new AuthSchemeOption.SignerPropertyConsumer() { diff --git a/core/sdk-core/src/main/java/software/amazon/awssdk/core/interceptor/SdkInternalExecutionAttribute.java b/core/sdk-core/src/main/java/software/amazon/awssdk/core/interceptor/SdkInternalExecutionAttribute.java index c83541d8d570..88852e0c3c86 100644 --- a/core/sdk-core/src/main/java/software/amazon/awssdk/core/interceptor/SdkInternalExecutionAttribute.java +++ b/core/sdk-core/src/main/java/software/amazon/awssdk/core/interceptor/SdkInternalExecutionAttribute.java @@ -177,7 +177,6 @@ public final class SdkInternalExecutionAttribute extends SdkExecutionAttribute { public static final ExecutionAttribute IDENTITY_PROVIDER_UPDATER = new ExecutionAttribute<>("IdentityProviderUpdater"); - /** /** * Callback to resolve auth scheme options from the (possibly modified) request. * Called by AuthSchemeResolutionStage after interceptors have run. From 6d725f29089324909ec52342eb9cd6d0f482b13e Mon Sep 17 00:00:00 2001 From: Saranya Somepalli Date: Fri, 15 May 2026 15:40:01 -0700 Subject: [PATCH 3/7] Address review comments --- .../internal/AwsExecutionContextBuilder.java | 2 +- .../core/http/auth/AuthSchemeResolver.java | 48 ++++++++++++------- .../SdkInternalExecutionAttribute.java | 10 ++-- .../stages/AuthSchemeResolutionStage.java | 2 +- .../stages/EndpointResolutionStage.java | 4 +- 5 files changed, 41 insertions(+), 25 deletions(-) diff --git a/core/aws-core/src/main/java/software/amazon/awssdk/awscore/internal/AwsExecutionContextBuilder.java b/core/aws-core/src/main/java/software/amazon/awssdk/awscore/internal/AwsExecutionContextBuilder.java index b5772197f481..b32ef96737fc 100644 --- a/core/aws-core/src/main/java/software/amazon/awssdk/awscore/internal/AwsExecutionContextBuilder.java +++ b/core/aws-core/src/main/java/software/amazon/awssdk/awscore/internal/AwsExecutionContextBuilder.java @@ -161,7 +161,7 @@ private AwsExecutionContextBuilder() { ExecutionInterceptorChain executionInterceptorChain = new ExecutionInterceptorChain(clientConfig.option(SdkClientOption.EXECUTION_INTERCEPTORS)); - executionAttributes.putAttribute(SdkInternalExecutionAttribute.AUTH_SCHEME_BEFORE_INTERCEPTORS, + executionAttributes.putAttribute(SdkInternalExecutionAttribute.AUTH_SCHEME_SNAPSHOT_PRE_INTERCEPTORS, executionAttributes.getAttribute(SdkInternalExecutionAttribute.SELECTED_AUTH_SCHEME)); InterceptorContext interceptorContext = InterceptorContext.builder() diff --git a/core/sdk-core/src/main/java/software/amazon/awssdk/core/http/auth/AuthSchemeResolver.java b/core/sdk-core/src/main/java/software/amazon/awssdk/core/http/auth/AuthSchemeResolver.java index 01c4e96e333a..20f6c81228e3 100644 --- a/core/sdk-core/src/main/java/software/amazon/awssdk/core/http/auth/AuthSchemeResolver.java +++ b/core/sdk-core/src/main/java/software/amazon/awssdk/core/http/auth/AuthSchemeResolver.java @@ -127,11 +127,15 @@ public static SelectedAuthScheme selectAuthScheme( /** * Merge properties from any pre-existing auth scheme into the selected one. + * + * After auth scheme resolution produces a fresh selectedAuthScheme, this method ensures that any signer properties + * explicitly set by interceptors (e.g., signing region override) take priority over the resolved values. */ public static SelectedAuthScheme mergePreExistingAuthSchemeProperties( SelectedAuthScheme selectedAuthScheme, ExecutionAttributes executionAttributes) { + // The "existing" auth scheme is what's currently on SELECTED_AUTH_SCHEME - potentially modified by interceptors. SelectedAuthScheme existingAuthScheme = executionAttributes.getAttribute(SdkInternalExecutionAttribute.SELECTED_AUTH_SCHEME); @@ -139,20 +143,27 @@ public static SelectedAuthScheme mergePreExistingAuthSch return selectedAuthScheme; } - SelectedAuthScheme beforeInterceptors = - executionAttributes.getAttribute(SdkInternalExecutionAttribute.AUTH_SCHEME_BEFORE_INTERCEPTORS); + // Snapshot taken before interceptors ran — used to detect what interceptors changed. + SelectedAuthScheme authSchemeBeforeInterceptors = + executionAttributes.getAttribute(SdkInternalExecutionAttribute.AUTH_SCHEME_SNAPSHOT_PRE_INTERCEPTORS); - if (beforeInterceptors != null && - beforeInterceptors.authSchemeOption() == existingAuthScheme.authSchemeOption()) { + // If the auth scheme option is the same object reference before and after + // interceptors, no interceptor modified it — skip the merge entirely. + if (authSchemeBeforeInterceptors != null && + authSchemeBeforeInterceptors.authSchemeOption() == existingAuthScheme.authSchemeOption()) { return selectedAuthScheme; } + // Start with the freshly resolved auth scheme as the base. AuthSchemeOption.Builder mergedOption = selectedAuthScheme.authSchemeOption().toBuilder(); + // For each signer property on the interceptor-modified scheme: + // If the interceptor changed it (differs from pre-interceptor snapshot), apply interceptor override + // If unchanged (same as before interceptors) only add if not already on the resolved scheme existingAuthScheme.authSchemeOption().forEachSignerProperty(new AuthSchemeOption.SignerPropertyConsumer() { @Override public void accept(SignerProperty key, S value) { - if (wasModifiedByInterceptor(beforeInterceptors, key, value)) { + if (wasModifiedByInterceptor(authSchemeBeforeInterceptors, key, value)) { mergedOption.putSignerProperty(key, value); } else { mergedOption.putSignerPropertyIfAbsent(key, value); @@ -169,12 +180,13 @@ public void accept(SignerProperty key, S value) { ); } - private static boolean wasModifiedByInterceptor(SelectedAuthScheme beforeInterceptors, + /** + * Returns true if the given property value differs from what it was before interceptors ran, + * meaning an interceptor explicitly changed it. + */ + private static boolean wasModifiedByInterceptor(SelectedAuthScheme authSchemeBeforeInterceptors, SignerProperty key, T currentValue) { - if (beforeInterceptors == null) { - return true; - } - T originalValue = beforeInterceptors.authSchemeOption().signerProperty(key); + T originalValue = authSchemeBeforeInterceptors.authSchemeOption().signerProperty(key); return !Objects.equals(originalValue, currentValue); } @@ -183,35 +195,39 @@ private static boolean wasModifiedByInterceptor(SelectedAuthScheme before * Called after endpoint resolution, which may have overwritten properties that interceptors set. */ public static void applyInterceptorModifiedProperties(SelectedAuthScheme currentScheme, - SelectedAuthScheme beforeInterceptors, - SelectedAuthScheme afterInterceptors, - ExecutionAttributes attrs) { + SelectedAuthScheme authSchemeBeforeInterceptors, + SelectedAuthScheme afterInterceptors, + ExecutionAttributes attrs) { if (afterInterceptors == null) { return; } - doApplyInterceptorModifiedProperties(currentScheme, beforeInterceptors, afterInterceptors, attrs); + doApplyInterceptorModifiedProperties(currentScheme, authSchemeBeforeInterceptors, afterInterceptors, attrs); } @SuppressWarnings("unchecked") private static void doApplyInterceptorModifiedProperties( SelectedAuthScheme currentScheme, - SelectedAuthScheme beforeInterceptors, + SelectedAuthScheme authSchemeBeforeInterceptors, SelectedAuthScheme afterInterceptors, ExecutionAttributes attrs) { + // Start with the current endpoint resolved auth scheme as the base. AuthSchemeOption.Builder mergedOption = currentScheme.authSchemeOption().toBuilder(); boolean[] changed = {false}; + // For each property on the post-interceptor scheme, check if the interceptor changed it. + // If yes, apply it onto the current scheme. afterInterceptors.authSchemeOption().forEachSignerProperty(new AuthSchemeOption.SignerPropertyConsumer() { @Override public void accept(SignerProperty key, S value) { - if (wasModifiedByInterceptor(beforeInterceptors, key, value)) { + if (wasModifiedByInterceptor(authSchemeBeforeInterceptors, key, value)) { mergedOption.putSignerProperty(key, value); changed[0] = true; } } }); + // Only update SELECTED_AUTH_SCHEME if at least one property was re-applied. if (changed[0]) { attrs.putAttribute(SdkInternalExecutionAttribute.SELECTED_AUTH_SCHEME, new SelectedAuthScheme<>(currentScheme.identity(), diff --git a/core/sdk-core/src/main/java/software/amazon/awssdk/core/interceptor/SdkInternalExecutionAttribute.java b/core/sdk-core/src/main/java/software/amazon/awssdk/core/interceptor/SdkInternalExecutionAttribute.java index 88852e0c3c86..8779a9cab996 100644 --- a/core/sdk-core/src/main/java/software/amazon/awssdk/core/interceptor/SdkInternalExecutionAttribute.java +++ b/core/sdk-core/src/main/java/software/amazon/awssdk/core/interceptor/SdkInternalExecutionAttribute.java @@ -209,16 +209,16 @@ public final class SdkInternalExecutionAttribute extends SdkExecutionAttribute { * Used by {@code AuthSchemeResolver#mergePreExistingAuthSchemeProperties} to detect which signer properties * were explicitly modified by interceptors (and should therefore override the freshly-resolved values). */ - public static final ExecutionAttribute> AUTH_SCHEME_BEFORE_INTERCEPTORS = - new ExecutionAttribute<>("AuthSchemeBeforeInterceptors"); + public static final ExecutionAttribute> AUTH_SCHEME_SNAPSHOT_PRE_INTERCEPTORS = + new ExecutionAttribute<>("AuthSchemeSnapshotPreInterceptors"); /** * Snapshot of {@link #SELECTED_AUTH_SCHEME} taken after interceptors run but before auth scheme resolution. - * Together with {@link #AUTH_SCHEME_BEFORE_INTERCEPTORS}, this allows detecting which signer properties + * Together with {@link #AUTH_SCHEME_SNAPSHOT_PRE_INTERCEPTORS}, this allows detecting which signer properties * were explicitly modified by interceptors so they can be re-applied after endpoint resolution. */ - public static final ExecutionAttribute> AUTH_SCHEME_AFTER_INTERCEPTORS = - new ExecutionAttribute<>("AuthSchemeAfterInterceptors"); + public static final ExecutionAttribute> AUTH_SCHEME_SNAPSHOT_POST_INTERCEPTORS = + new ExecutionAttribute<>("AuthSchemeSnapshotPostInterceptors"); /** * The supported compression algorithms for an operation, and whether the operation is streaming or not. diff --git a/core/sdk-core/src/main/java/software/amazon/awssdk/core/internal/http/pipeline/stages/AuthSchemeResolutionStage.java b/core/sdk-core/src/main/java/software/amazon/awssdk/core/internal/http/pipeline/stages/AuthSchemeResolutionStage.java index 35acd7bf8aaf..6146eb60208e 100644 --- a/core/sdk-core/src/main/java/software/amazon/awssdk/core/internal/http/pipeline/stages/AuthSchemeResolutionStage.java +++ b/core/sdk-core/src/main/java/software/amazon/awssdk/core/internal/http/pipeline/stages/AuthSchemeResolutionStage.java @@ -76,7 +76,7 @@ public SdkHttpFullRequest.Builder execute(SdkHttpFullRequest.Builder request, Re SelectedAuthScheme selectedAuthScheme = AuthSchemeResolver.selectAuthScheme(authOptions, authSchemes, identityProviders, metricCollector); - executionAttributes.putAttribute(SdkInternalExecutionAttribute.AUTH_SCHEME_AFTER_INTERCEPTORS, + executionAttributes.putAttribute(SdkInternalExecutionAttribute.AUTH_SCHEME_SNAPSHOT_POST_INTERCEPTORS, executionAttributes.getAttribute(SdkInternalExecutionAttribute.SELECTED_AUTH_SCHEME)); selectedAuthScheme = AuthSchemeResolver.mergePreExistingAuthSchemeProperties(selectedAuthScheme, executionAttributes); diff --git a/core/sdk-core/src/main/java/software/amazon/awssdk/core/internal/http/pipeline/stages/EndpointResolutionStage.java b/core/sdk-core/src/main/java/software/amazon/awssdk/core/internal/http/pipeline/stages/EndpointResolutionStage.java index e183f3ab16ce..6cfe0e54165a 100644 --- a/core/sdk-core/src/main/java/software/amazon/awssdk/core/internal/http/pipeline/stages/EndpointResolutionStage.java +++ b/core/sdk-core/src/main/java/software/amazon/awssdk/core/internal/http/pipeline/stages/EndpointResolutionStage.java @@ -151,10 +151,10 @@ private static void reapplyInterceptorModifiedAuthProperties(ExecutionAttributes return; } SelectedAuthScheme beforeInterceptors = - attrs.getAttribute(SdkInternalExecutionAttribute.AUTH_SCHEME_BEFORE_INTERCEPTORS); + attrs.getAttribute(SdkInternalExecutionAttribute.AUTH_SCHEME_SNAPSHOT_PRE_INTERCEPTORS); SelectedAuthScheme afterInterceptors = - attrs.getAttribute(SdkInternalExecutionAttribute.AUTH_SCHEME_AFTER_INTERCEPTORS); + attrs.getAttribute(SdkInternalExecutionAttribute.AUTH_SCHEME_SNAPSHOT_POST_INTERCEPTORS); if (afterInterceptors == null) { return; } From 18e02f504c968f30508f18b2007b429c15946324 Mon Sep 17 00:00:00 2001 From: Saranya Somepalli Date: Mon, 18 May 2026 15:08:43 -0700 Subject: [PATCH 4/7] Fix benchmark imports after merging from master --- .../benchmark/endpoints/LambdaEndpointResolverBenchmark.java | 4 ++-- .../benchmark/endpoints/S3EndpointResolverBenchmark.java | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/test/sdk-standard-benchmarks/src/main/java/software/amazon/awssdk/benchmark/endpoints/LambdaEndpointResolverBenchmark.java b/test/sdk-standard-benchmarks/src/main/java/software/amazon/awssdk/benchmark/endpoints/LambdaEndpointResolverBenchmark.java index 78e5a3fbd1aa..4efad1b6917a 100644 --- a/test/sdk-standard-benchmarks/src/main/java/software/amazon/awssdk/benchmark/endpoints/LambdaEndpointResolverBenchmark.java +++ b/test/sdk-standard-benchmarks/src/main/java/software/amazon/awssdk/benchmark/endpoints/LambdaEndpointResolverBenchmark.java @@ -38,7 +38,7 @@ import software.amazon.awssdk.regions.Region; import software.amazon.awssdk.services.lambda.endpoints.LambdaEndpointParams; import software.amazon.awssdk.services.lambda.endpoints.LambdaEndpointProvider; -import software.amazon.awssdk.services.lambda.endpoints.internal.LambdaResolveEndpointInterceptor; +import software.amazon.awssdk.services.lambda.endpoints.internal.LambdaEndpointResolverUtils; import software.amazon.awssdk.services.lambda.model.ListFunctionsRequest; import software.amazon.awssdk.utils.AttributeMap; @@ -88,7 +88,7 @@ public void setup() { @Benchmark public void resolveEndpoint(Blackhole blackhole) { - LambdaEndpointParams params = LambdaResolveEndpointInterceptor.ruleParams(request, executionAttributes); + LambdaEndpointParams params = LambdaEndpointResolverUtils.ruleParams(request, executionAttributes); blackhole.consume(provider.resolveEndpoint(params).join()); } diff --git a/test/sdk-standard-benchmarks/src/main/java/software/amazon/awssdk/benchmark/endpoints/S3EndpointResolverBenchmark.java b/test/sdk-standard-benchmarks/src/main/java/software/amazon/awssdk/benchmark/endpoints/S3EndpointResolverBenchmark.java index 9571040f3694..240891adcfdb 100644 --- a/test/sdk-standard-benchmarks/src/main/java/software/amazon/awssdk/benchmark/endpoints/S3EndpointResolverBenchmark.java +++ b/test/sdk-standard-benchmarks/src/main/java/software/amazon/awssdk/benchmark/endpoints/S3EndpointResolverBenchmark.java @@ -39,7 +39,7 @@ import software.amazon.awssdk.services.s3.endpoints.S3ClientContextParams; import software.amazon.awssdk.services.s3.endpoints.S3EndpointParams; import software.amazon.awssdk.services.s3.endpoints.S3EndpointProvider; -import software.amazon.awssdk.services.s3.endpoints.internal.S3ResolveEndpointInterceptor; +import software.amazon.awssdk.services.s3.endpoints.internal.S3EndpointResolverUtils; import software.amazon.awssdk.services.s3.model.GetObjectRequest; import software.amazon.awssdk.utils.AttributeMap; @@ -121,7 +121,7 @@ public void setup() { @Benchmark public void resolveEndpoint(Blackhole blackhole) { - S3EndpointParams params = S3ResolveEndpointInterceptor.ruleParams(request, executionAttributes); + S3EndpointParams params = S3EndpointResolverUtils.ruleParams(request, executionAttributes); blackhole.consume(provider.resolveEndpoint(params).join()); } From 00e558a395f27a6d8fe98aeea5083c16f1daed77 Mon Sep 17 00:00:00 2001 From: Saranya Somepalli Date: Tue, 19 May 2026 14:16:09 -0700 Subject: [PATCH 5/7] Fix test failures after master merge --- .../codegen/poet/client/ClientClassUtils.java | 11 +++++++++- .../core/http/auth/AuthSchemeResolver.java | 17 +++++++++++++--- ...EnableTrailingChecksumInterceptorTest.java | 20 ++++++++----------- 3 files changed, 32 insertions(+), 16 deletions(-) diff --git a/codegen/src/main/java/software/amazon/awssdk/codegen/poet/client/ClientClassUtils.java b/codegen/src/main/java/software/amazon/awssdk/codegen/poet/client/ClientClassUtils.java index 71c958c985e7..96fb6b05048f 100644 --- a/codegen/src/main/java/software/amazon/awssdk/codegen/poet/client/ClientClassUtils.java +++ b/codegen/src/main/java/software/amazon/awssdk/codegen/poet/client/ClientClassUtils.java @@ -371,7 +371,16 @@ static MethodSpec resolveAuthSchemeOptionsMethod(AuthSchemeSpecUtils authSchemeS ClassName providerInterface = authSchemeSpecUtils.providerInterfaceName(); - builder.addStatement("$T authSchemeProvider = $T.isInstanceOf($T.class, " + // Check for request-level authSchemeProvider override + builder.addStatement("$T requestAuthSchemeProvider = request.overrideConfiguration()" + + ".flatMap(c -> c.authSchemeProvider())" + + ".filter(p -> p instanceof $T)" + + ".map(p -> ($T) p)" + + ".orElse(null)", + providerInterface, providerInterface, providerInterface); + builder.addStatement("$T authSchemeProvider = requestAuthSchemeProvider != null " + + "? requestAuthSchemeProvider " + + ": $T.isInstanceOf($T.class, " + "clientConfiguration.option($T.AUTH_SCHEME_PROVIDER), $S)", providerInterface, Validate.class, providerInterface, SdkClientOption.class, "Expected an instance of " + authSchemeSpecUtils.providerInterfaceName().simpleName()); diff --git a/core/sdk-core/src/main/java/software/amazon/awssdk/core/http/auth/AuthSchemeResolver.java b/core/sdk-core/src/main/java/software/amazon/awssdk/core/http/auth/AuthSchemeResolver.java index 20f6c81228e3..27ec50412508 100644 --- a/core/sdk-core/src/main/java/software/amazon/awssdk/core/http/auth/AuthSchemeResolver.java +++ b/core/sdk-core/src/main/java/software/amazon/awssdk/core/http/auth/AuthSchemeResolver.java @@ -147,11 +147,19 @@ public static SelectedAuthScheme mergePreExistingAuthSch SelectedAuthScheme authSchemeBeforeInterceptors = executionAttributes.getAttribute(SdkInternalExecutionAttribute.AUTH_SCHEME_SNAPSHOT_PRE_INTERCEPTORS); - // If the auth scheme option is the same object reference before and after - // interceptors, no interceptor modified it — skip the merge entirely. + // If no interceptor modified the auth scheme option, skip the diff logic. Still merge existing properties with + // putIfAbsent so that properties from the initial placeholder (e.g., REGION_NAME) carry over to the + // freshly resolved scheme. if (authSchemeBeforeInterceptors != null && authSchemeBeforeInterceptors.authSchemeOption() == existingAuthScheme.authSchemeOption()) { - return selectedAuthScheme; + AuthSchemeOption.Builder mergedOption = selectedAuthScheme.authSchemeOption().toBuilder(); + existingAuthScheme.authSchemeOption().forEachSignerProperty(mergedOption::putSignerPropertyIfAbsent); + existingAuthScheme.authSchemeOption().forEachIdentityProperty(mergedOption::putIdentityPropertyIfAbsent); + return new SelectedAuthScheme<>( + selectedAuthScheme.identity(), + selectedAuthScheme.signer(), + mergedOption.build() + ); } // Start with the freshly resolved auth scheme as the base. @@ -186,6 +194,9 @@ public void accept(SignerProperty key, S value) { */ private static boolean wasModifiedByInterceptor(SelectedAuthScheme authSchemeBeforeInterceptors, SignerProperty key, T currentValue) { + if (authSchemeBeforeInterceptors == null) { + return false; + } T originalValue = authSchemeBeforeInterceptors.authSchemeOption().signerProperty(key); return !Objects.equals(originalValue, currentValue); } diff --git a/services/s3/src/test/java/software/amazon/awssdk/services/s3/internal/handlers/EnableTrailingChecksumInterceptorTest.java b/services/s3/src/test/java/software/amazon/awssdk/services/s3/internal/handlers/EnableTrailingChecksumInterceptorTest.java index f5e56277dca0..d1875027a32f 100644 --- a/services/s3/src/test/java/software/amazon/awssdk/services/s3/internal/handlers/EnableTrailingChecksumInterceptorTest.java +++ b/services/s3/src/test/java/software/amazon/awssdk/services/s3/internal/handlers/EnableTrailingChecksumInterceptorTest.java @@ -36,11 +36,8 @@ import software.amazon.awssdk.core.checksums.ResponseChecksumValidation; import software.amazon.awssdk.core.interceptor.Context; import software.amazon.awssdk.core.interceptor.ExecutionAttributes; -import software.amazon.awssdk.core.interceptor.SdkInternalExecutionAttribute; -import software.amazon.awssdk.endpoints.Endpoint; import software.amazon.awssdk.http.SdkHttpFullResponse; import software.amazon.awssdk.http.SdkHttpRequest; -import software.amazon.awssdk.services.s3.endpoints.internal.KnownS3ExpressEndpointProperty; import software.amazon.awssdk.services.s3.model.ChecksumMode; import software.amazon.awssdk.services.s3.model.GetObjectAclRequest; import software.amazon.awssdk.services.s3.model.GetObjectAclResponse; @@ -62,8 +59,8 @@ private static Stream getObjectRequestParams() { @ParameterizedTest @MethodSource("getObjectRequestParams") public void testGetObjectModifyRequest(boolean useS3Express, boolean disableChecksumValidation, boolean checksumModeEnabled) { - GetObjectRequest request = createGetObjectRequest(checksumModeEnabled); - ExecutionAttributes executionAttributes = createExecutionAttributes(disableChecksumValidation, useS3Express); + GetObjectRequest request = createGetObjectRequest(checksumModeEnabled, useS3Express); + ExecutionAttributes executionAttributes = createExecutionAttributes(disableChecksumValidation); Context.ModifyRequest modifyRequestContext = () -> request; SdkRequest modifiedRequest = interceptor.modifyRequest(modifyRequestContext, executionAttributes); @@ -106,8 +103,11 @@ private void validateGetObjectValues(SdkHttpRequest sdkHttpRequest, GetObjectReq } } - private GetObjectRequest createGetObjectRequest(boolean checksumModeEnabled) { + private GetObjectRequest createGetObjectRequest(boolean checksumModeEnabled, boolean isS3ExpressBucket) { GetObjectRequest.Builder requestBuilder = GetObjectRequest.builder(); + if (isS3ExpressBucket) { + requestBuilder.bucket("my-bucket--x-s3"); + } if (checksumModeEnabled) { requestBuilder.checksumMode(ChecksumMode.ENABLED); } @@ -120,7 +120,7 @@ public void modifyRequest_nonGetObjectRequest_shouldNotModify() { boolean useS3Express = false; boolean disableChecksumValidation = false; - ExecutionAttributes executionAttributes = createExecutionAttributes(disableChecksumValidation, useS3Express); + ExecutionAttributes executionAttributes = createExecutionAttributes(disableChecksumValidation); Context.ModifyRequest modifyRequestContext = () -> request; SdkRequest modifiedRequest = interceptor.modifyRequest(modifyRequestContext, executionAttributes); @@ -130,7 +130,7 @@ public void modifyRequest_nonGetObjectRequest_shouldNotModify() { assertThat(sdkHttpRequest.headers().get(ENABLE_CHECKSUM_REQUEST_HEADER)).isNull(); } - private ExecutionAttributes createExecutionAttributes(boolean disableChecksumValidation, boolean useS3Express) { + private ExecutionAttributes createExecutionAttributes(boolean disableChecksumValidation) { ExecutionAttributes executionAttributes = new ExecutionAttributes(); if (disableChecksumValidation) { executionAttributes.putAttribute(REQUEST_CHECKSUM_CALCULATION, RequestChecksumCalculation.WHEN_REQUIRED); @@ -139,10 +139,6 @@ private ExecutionAttributes createExecutionAttributes(boolean disableChecksumVal executionAttributes.putAttribute(REQUEST_CHECKSUM_CALCULATION, RequestChecksumCalculation.WHEN_SUPPORTED); executionAttributes.putAttribute(RESPONSE_CHECKSUM_VALIDATION, ResponseChecksumValidation.WHEN_SUPPORTED); } - if (useS3Express) { - Endpoint s3ExpressEndpoint = Endpoint.builder().putAttribute(KnownS3ExpressEndpointProperty.BACKEND, "S3Express").build(); - executionAttributes.putAttribute(SdkInternalExecutionAttribute.RESOLVED_ENDPOINT, s3ExpressEndpoint); - } return executionAttributes; } From 8d486f9edbf02b46c2f181dc68ec70605cfe24a5 Mon Sep 17 00:00:00 2001 From: Saranya Somepalli Date: Tue, 19 May 2026 14:31:31 -0700 Subject: [PATCH 6/7] Update codegen fixture files --- .../test-custom-context-params-async-client-class.java | 8 +++++--- .../codegen/poet/client/test-query-client-class.java | 8 +++++--- 2 files changed, 10 insertions(+), 6 deletions(-) diff --git a/codegen/src/test/resources/software/amazon/awssdk/codegen/poet/client/test-custom-context-params-async-client-class.java b/codegen/src/test/resources/software/amazon/awssdk/codegen/poet/client/test-custom-context-params-async-client-class.java index 168c55537fdc..b56fc767d7c9 100644 --- a/codegen/src/test/resources/software/amazon/awssdk/codegen/poet/client/test-custom-context-params-async-client-class.java +++ b/codegen/src/test/resources/software/amazon/awssdk/codegen/poet/client/test-custom-context-params-async-client-class.java @@ -197,9 +197,11 @@ private static List resolveMetricPublishers(SdkClientConfigurat private List resolveAuthSchemeOptions(SdkRequest request, String operationName, SdkClientConfiguration clientConfiguration) { - FooBarAuthSchemeProvider authSchemeProvider = Validate.isInstanceOf(FooBarAuthSchemeProvider.class, - clientConfiguration.option(SdkClientOption.AUTH_SCHEME_PROVIDER), - "Expected an instance of FooBarAuthSchemeProvider"); + FooBarAuthSchemeProvider requestAuthSchemeProvider = request.overrideConfiguration().flatMap(c -> c.authSchemeProvider()) + .filter(p -> p instanceof FooBarAuthSchemeProvider).map(p -> (FooBarAuthSchemeProvider) p).orElse(null); + FooBarAuthSchemeProvider authSchemeProvider = requestAuthSchemeProvider != null ? requestAuthSchemeProvider : Validate + .isInstanceOf(FooBarAuthSchemeProvider.class, clientConfiguration.option(SdkClientOption.AUTH_SCHEME_PROVIDER), + "Expected an instance of FooBarAuthSchemeProvider"); FooBarAuthSchemeParams.Builder paramsBuilder = FooBarAuthSchemeParams.builder().operation(operationName); paramsBuilder.region(clientConfiguration.option(AwsClientOption.AWS_REGION)); List options = authSchemeProvider.resolveAuthScheme(paramsBuilder.build()); diff --git a/codegen/src/test/resources/software/amazon/awssdk/codegen/poet/client/test-query-client-class.java b/codegen/src/test/resources/software/amazon/awssdk/codegen/poet/client/test-query-client-class.java index 661ca78263d5..077e589e4751 100644 --- a/codegen/src/test/resources/software/amazon/awssdk/codegen/poet/client/test-query-client-class.java +++ b/codegen/src/test/resources/software/amazon/awssdk/codegen/poet/client/test-query-client-class.java @@ -1095,9 +1095,11 @@ private static List resolveMetricPublishers(SdkClientConfigurat private List resolveAuthSchemeOptions(SdkRequest request, String operationName, SdkClientConfiguration clientConfiguration) { - QueryAuthSchemeProvider authSchemeProvider = Validate.isInstanceOf(QueryAuthSchemeProvider.class, - clientConfiguration.option(SdkClientOption.AUTH_SCHEME_PROVIDER), - "Expected an instance of QueryAuthSchemeProvider"); + QueryAuthSchemeProvider requestAuthSchemeProvider = request.overrideConfiguration().flatMap(c -> c.authSchemeProvider()) + .filter(p -> p instanceof QueryAuthSchemeProvider).map(p -> (QueryAuthSchemeProvider) p).orElse(null); + QueryAuthSchemeProvider authSchemeProvider = requestAuthSchemeProvider != null ? requestAuthSchemeProvider : Validate + .isInstanceOf(QueryAuthSchemeProvider.class, clientConfiguration.option(SdkClientOption.AUTH_SCHEME_PROVIDER), + "Expected an instance of QueryAuthSchemeProvider"); QueryAuthSchemeParams.Builder paramsBuilder = QueryAuthSchemeParams.builder().operation(operationName); paramsBuilder.region(clientConfiguration.option(AwsClientOption.AWS_REGION)); List options = authSchemeProvider.resolveAuthScheme(paramsBuilder.build()); From 8590c6287bcf7ec67c9b6355ce18b198d7b0a88e Mon Sep 17 00:00:00 2001 From: Saranya Somepalli Date: Tue, 19 May 2026 15:26:37 -0700 Subject: [PATCH 7/7] Address review comments --- .../awssdk/codegen/poet/client/ClientClassUtils.java | 6 +++--- .../test-custom-context-params-async-client-class.java | 7 +++++-- .../codegen/poet/client/test-query-client-class.java | 7 +++++-- 3 files changed, 13 insertions(+), 7 deletions(-) diff --git a/codegen/src/main/java/software/amazon/awssdk/codegen/poet/client/ClientClassUtils.java b/codegen/src/main/java/software/amazon/awssdk/codegen/poet/client/ClientClassUtils.java index 96fb6b05048f..9684be34b02e 100644 --- a/codegen/src/main/java/software/amazon/awssdk/codegen/poet/client/ClientClassUtils.java +++ b/codegen/src/main/java/software/amazon/awssdk/codegen/poet/client/ClientClassUtils.java @@ -374,10 +374,10 @@ static MethodSpec resolveAuthSchemeOptionsMethod(AuthSchemeSpecUtils authSchemeS // Check for request-level authSchemeProvider override builder.addStatement("$T requestAuthSchemeProvider = request.overrideConfiguration()" + ".flatMap(c -> c.authSchemeProvider())" - + ".filter(p -> p instanceof $T)" - + ".map(p -> ($T) p)" + + ".map(p -> $T.isInstanceOf($T.class, p, $S))" + ".orElse(null)", - providerInterface, providerInterface, providerInterface); + providerInterface, Validate.class, providerInterface, + "Expected an instance of " + authSchemeSpecUtils.providerInterfaceName().simpleName()); builder.addStatement("$T authSchemeProvider = requestAuthSchemeProvider != null " + "? requestAuthSchemeProvider " + ": $T.isInstanceOf($T.class, " diff --git a/codegen/src/test/resources/software/amazon/awssdk/codegen/poet/client/test-custom-context-params-async-client-class.java b/codegen/src/test/resources/software/amazon/awssdk/codegen/poet/client/test-custom-context-params-async-client-class.java index b56fc767d7c9..a1701b2a6df6 100644 --- a/codegen/src/test/resources/software/amazon/awssdk/codegen/poet/client/test-custom-context-params-async-client-class.java +++ b/codegen/src/test/resources/software/amazon/awssdk/codegen/poet/client/test-custom-context-params-async-client-class.java @@ -197,8 +197,11 @@ private static List resolveMetricPublishers(SdkClientConfigurat private List resolveAuthSchemeOptions(SdkRequest request, String operationName, SdkClientConfiguration clientConfiguration) { - FooBarAuthSchemeProvider requestAuthSchemeProvider = request.overrideConfiguration().flatMap(c -> c.authSchemeProvider()) - .filter(p -> p instanceof FooBarAuthSchemeProvider).map(p -> (FooBarAuthSchemeProvider) p).orElse(null); + FooBarAuthSchemeProvider requestAuthSchemeProvider = request + .overrideConfiguration() + .flatMap(c -> c.authSchemeProvider()) + .map(p -> Validate.isInstanceOf(FooBarAuthSchemeProvider.class, p, + "Expected an instance of FooBarAuthSchemeProvider")).orElse(null); FooBarAuthSchemeProvider authSchemeProvider = requestAuthSchemeProvider != null ? requestAuthSchemeProvider : Validate .isInstanceOf(FooBarAuthSchemeProvider.class, clientConfiguration.option(SdkClientOption.AUTH_SCHEME_PROVIDER), "Expected an instance of FooBarAuthSchemeProvider"); diff --git a/codegen/src/test/resources/software/amazon/awssdk/codegen/poet/client/test-query-client-class.java b/codegen/src/test/resources/software/amazon/awssdk/codegen/poet/client/test-query-client-class.java index 077e589e4751..98f0bf1b1f82 100644 --- a/codegen/src/test/resources/software/amazon/awssdk/codegen/poet/client/test-query-client-class.java +++ b/codegen/src/test/resources/software/amazon/awssdk/codegen/poet/client/test-query-client-class.java @@ -1095,8 +1095,11 @@ private static List resolveMetricPublishers(SdkClientConfigurat private List resolveAuthSchemeOptions(SdkRequest request, String operationName, SdkClientConfiguration clientConfiguration) { - QueryAuthSchemeProvider requestAuthSchemeProvider = request.overrideConfiguration().flatMap(c -> c.authSchemeProvider()) - .filter(p -> p instanceof QueryAuthSchemeProvider).map(p -> (QueryAuthSchemeProvider) p).orElse(null); + QueryAuthSchemeProvider requestAuthSchemeProvider = request + .overrideConfiguration() + .flatMap(c -> c.authSchemeProvider()) + .map(p -> Validate.isInstanceOf(QueryAuthSchemeProvider.class, p, + "Expected an instance of QueryAuthSchemeProvider")).orElse(null); QueryAuthSchemeProvider authSchemeProvider = requestAuthSchemeProvider != null ? requestAuthSchemeProvider : Validate .isInstanceOf(QueryAuthSchemeProvider.class, clientConfiguration.option(SdkClientOption.AUTH_SCHEME_PROVIDER), "Expected an instance of QueryAuthSchemeProvider");