From 33d70c575a0d6a34dddd732edc88ef31032f82c8 Mon Sep 17 00:00:00 2001 From: ssyed74 Date: Mon, 20 Jul 2026 15:06:07 -0400 Subject: [PATCH 1/4] fix region being resolved before plugins are run --- .../core/client/builder/SdkDefaultClientBuilder.java | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/core/sdk-core/src/main/java/software/amazon/awssdk/core/client/builder/SdkDefaultClientBuilder.java b/core/sdk-core/src/main/java/software/amazon/awssdk/core/client/builder/SdkDefaultClientBuilder.java index 34f165dd1767..1ff44b3e31d4 100644 --- a/core/sdk-core/src/main/java/software/amazon/awssdk/core/client/builder/SdkDefaultClientBuilder.java +++ b/core/sdk-core/src/main/java/software/amazon/awssdk/core/client/builder/SdkDefaultClientBuilder.java @@ -202,14 +202,14 @@ protected final SdkClientConfiguration syncClientConfiguration() { configuration = mergeChildDefaults(configuration); configuration = mergeGlobalDefaults(configuration); + // Invoke the plugins + configuration = invokePlugins(configuration); + // Create additional configuration from the default-applied configuration configuration = finalizeChildConfiguration(configuration); configuration = finalizeSyncConfiguration(configuration); configuration = finalizeConfiguration(configuration); - // Invoke the plugins - configuration = invokePlugins(configuration); - return configuration; } @@ -233,14 +233,14 @@ protected final SdkClientConfiguration asyncClientConfiguration() { configuration = mergeChildDefaults(configuration); configuration = mergeGlobalDefaults(configuration); + // Invoke the plugins + configuration = invokePlugins(configuration); + // Create additional configuration from the default-applied configuration configuration = finalizeChildConfiguration(configuration); configuration = finalizeAsyncConfiguration(configuration); configuration = finalizeConfiguration(configuration); - // Invoke the plugins - configuration = invokePlugins(configuration); - return configuration; } From 7439a9ad898ae5abb6b7fc9bc370083cde241322 Mon Sep 17 00:00:00 2001 From: ssyed74 Date: Tue, 21 Jul 2026 09:28:38 -0400 Subject: [PATCH 2/4] Add the changelog --- .changes/next-release/bugfix-AWSSDKforJavav2-238f31f.json | 6 ++++++ 1 file changed, 6 insertions(+) create mode 100644 .changes/next-release/bugfix-AWSSDKforJavav2-238f31f.json diff --git a/.changes/next-release/bugfix-AWSSDKforJavav2-238f31f.json b/.changes/next-release/bugfix-AWSSDKforJavav2-238f31f.json new file mode 100644 index 000000000000..fa5fbf52a05d --- /dev/null +++ b/.changes/next-release/bugfix-AWSSDKforJavav2-238f31f.json @@ -0,0 +1,6 @@ +{ + "type": "bugfix", + "category": "AWS SDK for Java v2", + "contributor": "Techno3d", + "description": "Fix a bug where an SDK Client that has a plugin which supplies a region would throw an SdkClientException stating that no region was set." +} From 950eb92fce31c59525a287633a8cd7a38f76eb34 Mon Sep 17 00:00:00 2001 From: ssyed74 Date: Tue, 21 Jul 2026 13:19:20 -0400 Subject: [PATCH 3/4] Add test case to SdkPluginTest to check if an SdkPlugin can set a region when no region was set --- .../amazon/awssdk/services/SdkPluginTest.java | 41 +++++++++++++++---- 1 file changed, 32 insertions(+), 9 deletions(-) diff --git a/test/codegen-generated-classes-test/src/test/java/software/amazon/awssdk/services/SdkPluginTest.java b/test/codegen-generated-classes-test/src/test/java/software/amazon/awssdk/services/SdkPluginTest.java index f36061fe8583..da65e560814f 100644 --- a/test/codegen-generated-classes-test/src/test/java/software/amazon/awssdk/services/SdkPluginTest.java +++ b/test/codegen-generated-classes-test/src/test/java/software/amazon/awssdk/services/SdkPluginTest.java @@ -158,6 +158,19 @@ public static Stream> testCases() { .contains(v.id()); assertThat(r.httpRequest().getUri().getHost()).contains(v.id()); }), + new TestCase("noDefaultRegion") + .useNoRegionClient() + .nonDefaultValue(Region.US_EAST_1) + .clientSetter(AwsClientBuilder::region) + .pluginSetter(ProtocolRestJsonServiceClientConfiguration.Builder::region) + .pluginValidator((c, v) -> assertThat(c.region()).isEqualTo(v)) + .beforeTransmissionValidator((r, a, v) -> { + assertThat(r.httpRequest() + .firstMatchingHeader("Authorization")).get() + .asString() + .contains(v.id()); + assertThat(r.httpRequest().getUri().getHost()).contains(v.id()); + }), new TestCase("credentialsProvider") .defaultValue(DEFAULT_CREDENTIALS) .nonDefaultValue(DEFAULT_CREDENTIALS::resolveCredentials) @@ -378,7 +391,7 @@ public void validateTestCaseData(TestCase testCase) { @ParameterizedTest @MethodSource("testCases") public void clientPluginSeesDefaultValue(TestCase testCase) { - ProtocolRestJsonClientBuilder clientBuilder = defaultClientBuilder(); + ProtocolRestJsonClientBuilder clientBuilder = defaultClientBuilder(testCase.noRegionClient); AtomicInteger timesCalled = new AtomicInteger(0); SdkPlugin plugin = config -> { @@ -398,7 +411,7 @@ public void clientPluginSeesDefaultValue(TestCase testCase) { @ParameterizedTest @MethodSource("testCases") public void requestPluginSeesDefaultValue(TestCase testCase) { - ProtocolRestJsonClientBuilder clientBuilder = defaultClientBuilder(); + ProtocolRestJsonClientBuilder clientBuilder = defaultClientBuilder(testCase.noRegionClient); AtomicInteger timesCalled = new AtomicInteger(0); SdkPlugin plugin = config -> { @@ -419,7 +432,7 @@ public void requestPluginSeesDefaultValue(TestCase testCase) { @ParameterizedTest @MethodSource("testCases") public void clientPluginSeesCustomerClientConfiguredValue(TestCase testCase) { - ProtocolRestJsonClientBuilder clientBuilder = defaultClientBuilder(); + ProtocolRestJsonClientBuilder clientBuilder = defaultClientBuilder(testCase.noRegionClient); testCase.clientSetter.accept(clientBuilder, testCase.nonDefaultValue); AtomicInteger timesCalled = new AtomicInteger(0); @@ -442,7 +455,7 @@ public void clientPluginSeesCustomerClientConfiguredValue(TestCase testCa @ParameterizedTest @MethodSource("testCases") public void requestPluginSeesCustomerClientConfiguredValue(TestCase testCase) { - ProtocolRestJsonClientBuilder clientBuilder = defaultClientBuilder(); + ProtocolRestJsonClientBuilder clientBuilder = defaultClientBuilder(testCase.noRegionClient); testCase.clientSetter.accept(clientBuilder, testCase.nonDefaultValue); AtomicInteger timesCalled = new AtomicInteger(0); @@ -469,7 +482,7 @@ public void requestPluginSeesCustomerRequestConfiguredValue(TestCase test return; } - ProtocolRestJsonClientBuilder clientBuilder = defaultClientBuilder(); + ProtocolRestJsonClientBuilder clientBuilder = defaultClientBuilder(testCase.noRegionClient); AtomicInteger timesCalled = new AtomicInteger(0); SdkPlugin plugin = config -> { @@ -502,7 +515,7 @@ public void requestPluginSeesCustomerRequestConfiguredValue(TestCase test @ParameterizedTest @MethodSource("testCases") public void clientPluginSetValueIsUsed(TestCase testCase) { - ProtocolRestJsonClientBuilder clientBuilder = defaultClientBuilder(); + ProtocolRestJsonClientBuilder clientBuilder = defaultClientBuilder(testCase.noRegionClient); testCase.clientSetter.accept(clientBuilder, testCase.defaultValue); AtomicInteger timesPluginCalled = new AtomicInteger(0); @@ -543,7 +556,7 @@ public void beforeTransmission(Context.BeforeTransmission context, ExecutionAttr @ParameterizedTest @MethodSource("testCases") public void requestPluginSetValueIsUsed(TestCase testCase) { - ProtocolRestJsonClientBuilder clientBuilder = defaultClientBuilder(); + ProtocolRestJsonClientBuilder clientBuilder = defaultClientBuilder(testCase.noRegionClient); testCase.clientSetter.accept(clientBuilder, testCase.defaultValue); AtomicInteger timesPluginCalled = new AtomicInteger(0); @@ -595,8 +608,12 @@ public void beforeTransmission(Context.BeforeTransmission context, ExecutionAttr assertThat(timesInterceptorCalled).hasValueGreaterThanOrEqualTo(1); } - private static ProtocolRestJsonClientBuilder defaultClientBuilder() { - return ProtocolRestJsonClient.builder().region(Region.US_WEST_2).credentialsProvider(DEFAULT_CREDENTIALS); + private static ProtocolRestJsonClientBuilder defaultClientBuilder(boolean useNoRegionClient) { + if (useNoRegionClient) { + return ProtocolRestJsonClient.builder().credentialsProvider(DEFAULT_CREDENTIALS); + } else { + return ProtocolRestJsonClient.builder().region(Region.US_WEST_2).credentialsProvider(DEFAULT_CREDENTIALS); + } } private SdkClientConfiguration extractClientConfiguration(ProtocolRestJsonClient client) { @@ -613,6 +630,7 @@ private SdkClientConfiguration extractClientConfiguration(ProtocolRestJsonClient static class TestCase { private final String configName; + boolean noRegionClient = false; T defaultValue; T nonDefaultValue; BiConsumer clientSetter; @@ -667,6 +685,11 @@ public TestCase beforeTransmissionValidator(TriConsumer useNoRegionClient() { + this.noRegionClient = true; + return this; + } + @Override public String toString() { return configName; From 89878dd2026403047c3c30439cf36ccc2d374932 Mon Sep 17 00:00:00 2001 From: ssyed74 Date: Tue, 21 Jul 2026 17:04:11 -0400 Subject: [PATCH 4/4] new tests --- .../amazon/awssdk/services/SdkPluginTest.java | 51 +++++++------------ 1 file changed, 19 insertions(+), 32 deletions(-) diff --git a/test/codegen-generated-classes-test/src/test/java/software/amazon/awssdk/services/SdkPluginTest.java b/test/codegen-generated-classes-test/src/test/java/software/amazon/awssdk/services/SdkPluginTest.java index da65e560814f..1b3bd4240582 100644 --- a/test/codegen-generated-classes-test/src/test/java/software/amazon/awssdk/services/SdkPluginTest.java +++ b/test/codegen-generated-classes-test/src/test/java/software/amazon/awssdk/services/SdkPluginTest.java @@ -40,6 +40,7 @@ import java.util.stream.Stream; import org.junit.jupiter.params.ParameterizedTest; import org.junit.jupiter.params.provider.MethodSource; +import org.junit.jupiter.api.Test; import org.mockito.Mockito; import software.amazon.awssdk.auth.credentials.AwsBasicCredentials; import software.amazon.awssdk.auth.credentials.AwsCredentialsProvider; @@ -158,19 +159,6 @@ public static Stream> testCases() { .contains(v.id()); assertThat(r.httpRequest().getUri().getHost()).contains(v.id()); }), - new TestCase("noDefaultRegion") - .useNoRegionClient() - .nonDefaultValue(Region.US_EAST_1) - .clientSetter(AwsClientBuilder::region) - .pluginSetter(ProtocolRestJsonServiceClientConfiguration.Builder::region) - .pluginValidator((c, v) -> assertThat(c.region()).isEqualTo(v)) - .beforeTransmissionValidator((r, a, v) -> { - assertThat(r.httpRequest() - .firstMatchingHeader("Authorization")).get() - .asString() - .contains(v.id()); - assertThat(r.httpRequest().getUri().getHost()).contains(v.id()); - }), new TestCase("credentialsProvider") .defaultValue(DEFAULT_CREDENTIALS) .nonDefaultValue(DEFAULT_CREDENTIALS::resolveCredentials) @@ -391,7 +379,7 @@ public void validateTestCaseData(TestCase testCase) { @ParameterizedTest @MethodSource("testCases") public void clientPluginSeesDefaultValue(TestCase testCase) { - ProtocolRestJsonClientBuilder clientBuilder = defaultClientBuilder(testCase.noRegionClient); + ProtocolRestJsonClientBuilder clientBuilder = defaultClientBuilder(); AtomicInteger timesCalled = new AtomicInteger(0); SdkPlugin plugin = config -> { @@ -411,7 +399,7 @@ public void clientPluginSeesDefaultValue(TestCase testCase) { @ParameterizedTest @MethodSource("testCases") public void requestPluginSeesDefaultValue(TestCase testCase) { - ProtocolRestJsonClientBuilder clientBuilder = defaultClientBuilder(testCase.noRegionClient); + ProtocolRestJsonClientBuilder clientBuilder = defaultClientBuilder(); AtomicInteger timesCalled = new AtomicInteger(0); SdkPlugin plugin = config -> { @@ -432,7 +420,7 @@ public void requestPluginSeesDefaultValue(TestCase testCase) { @ParameterizedTest @MethodSource("testCases") public void clientPluginSeesCustomerClientConfiguredValue(TestCase testCase) { - ProtocolRestJsonClientBuilder clientBuilder = defaultClientBuilder(testCase.noRegionClient); + ProtocolRestJsonClientBuilder clientBuilder = defaultClientBuilder(); testCase.clientSetter.accept(clientBuilder, testCase.nonDefaultValue); AtomicInteger timesCalled = new AtomicInteger(0); @@ -455,7 +443,7 @@ public void clientPluginSeesCustomerClientConfiguredValue(TestCase testCa @ParameterizedTest @MethodSource("testCases") public void requestPluginSeesCustomerClientConfiguredValue(TestCase testCase) { - ProtocolRestJsonClientBuilder clientBuilder = defaultClientBuilder(testCase.noRegionClient); + ProtocolRestJsonClientBuilder clientBuilder = defaultClientBuilder(); testCase.clientSetter.accept(clientBuilder, testCase.nonDefaultValue); AtomicInteger timesCalled = new AtomicInteger(0); @@ -482,7 +470,7 @@ public void requestPluginSeesCustomerRequestConfiguredValue(TestCase test return; } - ProtocolRestJsonClientBuilder clientBuilder = defaultClientBuilder(testCase.noRegionClient); + ProtocolRestJsonClientBuilder clientBuilder = defaultClientBuilder(); AtomicInteger timesCalled = new AtomicInteger(0); SdkPlugin plugin = config -> { @@ -515,7 +503,7 @@ public void requestPluginSeesCustomerRequestConfiguredValue(TestCase test @ParameterizedTest @MethodSource("testCases") public void clientPluginSetValueIsUsed(TestCase testCase) { - ProtocolRestJsonClientBuilder clientBuilder = defaultClientBuilder(testCase.noRegionClient); + ProtocolRestJsonClientBuilder clientBuilder = defaultClientBuilder(); testCase.clientSetter.accept(clientBuilder, testCase.defaultValue); AtomicInteger timesPluginCalled = new AtomicInteger(0); @@ -556,7 +544,7 @@ public void beforeTransmission(Context.BeforeTransmission context, ExecutionAttr @ParameterizedTest @MethodSource("testCases") public void requestPluginSetValueIsUsed(TestCase testCase) { - ProtocolRestJsonClientBuilder clientBuilder = defaultClientBuilder(testCase.noRegionClient); + ProtocolRestJsonClientBuilder clientBuilder = defaultClientBuilder(); testCase.clientSetter.accept(clientBuilder, testCase.defaultValue); AtomicInteger timesPluginCalled = new AtomicInteger(0); @@ -608,12 +596,17 @@ public void beforeTransmission(Context.BeforeTransmission context, ExecutionAttr assertThat(timesInterceptorCalled).hasValueGreaterThanOrEqualTo(1); } - private static ProtocolRestJsonClientBuilder defaultClientBuilder(boolean useNoRegionClient) { - if (useNoRegionClient) { - return ProtocolRestJsonClient.builder().credentialsProvider(DEFAULT_CREDENTIALS); - } else { - return ProtocolRestJsonClient.builder().region(Region.US_WEST_2).credentialsProvider(DEFAULT_CREDENTIALS); - } + @Test + public void pluginSetRegionIsUsed() { + ProtocolRestJsonClient client = ProtocolRestJsonClient.builder() + .addPlugin(config -> ((ProtocolRestJsonServiceClientConfiguration.Builder) config).region(Region.US_EAST_1)) + .credentialsProvider(DEFAULT_CREDENTIALS) + .build(); + assertThat(client.serviceClientConfiguration().region()).isEqualTo(Region.US_EAST_1); + } + + private static ProtocolRestJsonClientBuilder defaultClientBuilder() { + return ProtocolRestJsonClient.builder().region(Region.US_WEST_2).credentialsProvider(DEFAULT_CREDENTIALS); } private SdkClientConfiguration extractClientConfiguration(ProtocolRestJsonClient client) { @@ -630,7 +623,6 @@ private SdkClientConfiguration extractClientConfiguration(ProtocolRestJsonClient static class TestCase { private final String configName; - boolean noRegionClient = false; T defaultValue; T nonDefaultValue; BiConsumer clientSetter; @@ -685,11 +677,6 @@ public TestCase beforeTransmissionValidator(TriConsumer useNoRegionClient() { - this.noRegionClient = true; - return this; - } - @Override public String toString() { return configName;