diff --git a/.changes/next-release/feature-AWSSDKforJavav2-f449613.json b/.changes/next-release/feature-AWSSDKforJavav2-f449613.json new file mode 100644 index 000000000000..58693fa07029 --- /dev/null +++ b/.changes/next-release/feature-AWSSDKforJavav2-f449613.json @@ -0,0 +1,6 @@ +{ + "category": "AWS SDK for Java v2", + "contributor": "", + "type": "feature", + "description": "Exposes endpointOverride in SdkClient through ServiceClientConfiguration" +} diff --git a/codegen/src/main/java/software/amazon/awssdk/codegen/poet/builder/AsyncClientBuilderClass.java b/codegen/src/main/java/software/amazon/awssdk/codegen/poet/builder/AsyncClientBuilderClass.java index c2cb9d6dd2b1..f8731d7dad07 100644 --- a/codegen/src/main/java/software/amazon/awssdk/codegen/poet/builder/AsyncClientBuilderClass.java +++ b/codegen/src/main/java/software/amazon/awssdk/codegen/poet/builder/AsyncClientBuilderClass.java @@ -19,6 +19,7 @@ import com.squareup.javapoet.MethodSpec; import com.squareup.javapoet.ParameterizedTypeName; import com.squareup.javapoet.TypeSpec; +import java.net.URI; import javax.lang.model.element.Modifier; import software.amazon.awssdk.annotations.SdkInternalApi; import software.amazon.awssdk.auth.token.credentials.SdkTokenProvider; @@ -124,9 +125,17 @@ private MethodSpec buildClientMethod() { .returns(clientInterfaceName) .addStatement("$T clientConfiguration = super.asyncClientConfiguration()", SdkClientConfiguration.class) .addStatement("this.validateClientOptions(clientConfiguration)") + .addStatement("$T endpointOverride = null", URI.class) + .addCode("if (clientConfiguration.option($T.ENDPOINT_OVERRIDDEN) != null" + + "&& $T.TRUE.equals(clientConfiguration.option($T.ENDPOINT_OVERRIDDEN))) {" + + "endpointOverride = clientConfiguration.option($T.ENDPOINT);" + + "}", + SdkClientOption.class, Boolean.class, SdkClientOption.class, SdkClientOption.class) .addStatement("$T serviceClientConfiguration = $T.builder()" + ".overrideConfiguration(overrideConfiguration())" - + ".region(clientConfiguration.option($T.AWS_REGION)).build()", + + ".region(clientConfiguration.option($T.AWS_REGION))" + + ".endpointOverride(endpointOverride)" + + ".build()", serviceConfigClassName, serviceConfigClassName, AwsClientOption.class) .addStatement("return new $T(serviceClientConfiguration, clientConfiguration)", clientClassName) .build(); diff --git a/codegen/src/main/java/software/amazon/awssdk/codegen/poet/builder/SyncClientBuilderClass.java b/codegen/src/main/java/software/amazon/awssdk/codegen/poet/builder/SyncClientBuilderClass.java index b0d68d247257..036589de04e8 100644 --- a/codegen/src/main/java/software/amazon/awssdk/codegen/poet/builder/SyncClientBuilderClass.java +++ b/codegen/src/main/java/software/amazon/awssdk/codegen/poet/builder/SyncClientBuilderClass.java @@ -19,6 +19,7 @@ import com.squareup.javapoet.MethodSpec; import com.squareup.javapoet.ParameterizedTypeName; import com.squareup.javapoet.TypeSpec; +import java.net.URI; import javax.lang.model.element.Modifier; import software.amazon.awssdk.annotations.SdkInternalApi; import software.amazon.awssdk.auth.token.credentials.SdkTokenProvider; @@ -124,9 +125,17 @@ private MethodSpec buildClientMethod() { .returns(clientInterfaceName) .addStatement("$T clientConfiguration = super.syncClientConfiguration()", SdkClientConfiguration.class) .addStatement("this.validateClientOptions(clientConfiguration)") + .addStatement("$T endpointOverride = null", URI.class) + .addCode("if (clientConfiguration.option($T.ENDPOINT_OVERRIDDEN) != null" + + "&& $T.TRUE.equals(clientConfiguration.option($T.ENDPOINT_OVERRIDDEN))) {" + + "endpointOverride = clientConfiguration.option($T.ENDPOINT);" + + "}", + SdkClientOption.class, Boolean.class, SdkClientOption.class, SdkClientOption.class) .addStatement("$T serviceClientConfiguration = $T.builder()" + ".overrideConfiguration(overrideConfiguration())" - + ".region(clientConfiguration.option($T.AWS_REGION)).build()", + + ".region(clientConfiguration.option($T.AWS_REGION))" + + ".endpointOverride(endpointOverride)" + + ".build()", serviceConfigClassName, serviceConfigClassName, AwsClientOption.class) .addStatement("return new $T(serviceClientConfiguration, clientConfiguration)", clientClassName) .build(); diff --git a/codegen/src/main/java/software/amazon/awssdk/codegen/poet/model/ServiceClientConfigurationClass.java b/codegen/src/main/java/software/amazon/awssdk/codegen/poet/model/ServiceClientConfigurationClass.java index e12afe4bcdc6..1d3d258ef01b 100644 --- a/codegen/src/main/java/software/amazon/awssdk/codegen/poet/model/ServiceClientConfigurationClass.java +++ b/codegen/src/main/java/software/amazon/awssdk/codegen/poet/model/ServiceClientConfigurationClass.java @@ -24,6 +24,7 @@ import com.squareup.javapoet.ClassName; import com.squareup.javapoet.MethodSpec; import com.squareup.javapoet.TypeSpec; +import java.net.URI; import software.amazon.awssdk.annotations.SdkPublicApi; import software.amazon.awssdk.awscore.AwsServiceClientConfiguration; import software.amazon.awssdk.codegen.model.intermediate.IntermediateModel; @@ -89,12 +90,21 @@ private TypeSpec builderInterfaceSpec() { .returns(className()) .build()) .addMethod(MethodSpec.methodBuilder("region") + .addAnnotation(Override.class) .addModifiers(PUBLIC, ABSTRACT) .addParameter(Region.class, "region") .returns(className().nestedClass("Builder")) .addJavadoc("Configure the region") .build()) + .addMethod(MethodSpec.methodBuilder("endpointOverride") + .addAnnotation(Override.class) + .addModifiers(PUBLIC, ABSTRACT) + .addParameter(URI.class, "endpointOverride") + .returns(className().nestedClass("Builder")) + .addJavadoc("Configure the endpointOverride") + .build()) .addMethod(MethodSpec.methodBuilder("overrideConfiguration") + .addAnnotation(Override.class) .addModifiers(PUBLIC, ABSTRACT) .addParameter(ClientOverrideConfiguration.class, "clientOverrideConfiguration") .returns(className().nestedClass("Builder")) @@ -132,6 +142,14 @@ private TypeSpec builderImplSpec() { .addStatement("this.overrideConfiguration = clientOverrideConfiguration") .addStatement("return this") .build()) + .addMethod(MethodSpec.methodBuilder("endpointOverride") + .addAnnotation(Override.class) + .addModifiers(PUBLIC) + .addParameter(URI.class, "endpointOverride") + .returns(className().nestedClass("Builder")) + .addStatement("this.endpointOverride = endpointOverride") + .addStatement("return this") + .build()) .addMethod(MethodSpec.methodBuilder("build") .addAnnotation(Override.class) .addModifiers(PUBLIC) diff --git a/codegen/src/test/resources/software/amazon/awssdk/codegen/poet/builder/test-async-client-builder-class.java b/codegen/src/test/resources/software/amazon/awssdk/codegen/poet/builder/test-async-client-builder-class.java index ecc0a285c369..61101024dda9 100644 --- a/codegen/src/test/resources/software/amazon/awssdk/codegen/poet/builder/test-async-client-builder-class.java +++ b/codegen/src/test/resources/software/amazon/awssdk/codegen/poet/builder/test-async-client-builder-class.java @@ -1,5 +1,6 @@ package software.amazon.awssdk.services.json; +import java.net.URI; import software.amazon.awssdk.annotations.Generated; import software.amazon.awssdk.annotations.SdkInternalApi; import software.amazon.awssdk.auth.token.credentials.SdkTokenProvider; @@ -31,9 +32,14 @@ public DefaultJsonAsyncClientBuilder tokenProvider(SdkTokenProvider tokenProvide protected final JsonAsyncClient buildClient() { SdkClientConfiguration clientConfiguration = super.asyncClientConfiguration(); this.validateClientOptions(clientConfiguration); + URI endpointOverride = null; + if (clientConfiguration.option(SdkClientOption.ENDPOINT_OVERRIDDEN) != null + && Boolean.TRUE.equals(clientConfiguration.option(SdkClientOption.ENDPOINT_OVERRIDDEN))) { + endpointOverride = clientConfiguration.option(SdkClientOption.ENDPOINT); + } JsonServiceClientConfiguration serviceClientConfiguration = JsonServiceClientConfiguration.builder() .overrideConfiguration(overrideConfiguration()).region(clientConfiguration.option(AwsClientOption.AWS_REGION)) - .build(); + .endpointOverride(endpointOverride).build(); return new DefaultJsonAsyncClient(serviceClientConfiguration, clientConfiguration); } } diff --git a/codegen/src/test/resources/software/amazon/awssdk/codegen/poet/builder/test-sync-client-builder-class.java b/codegen/src/test/resources/software/amazon/awssdk/codegen/poet/builder/test-sync-client-builder-class.java index d7ea0320a00f..64b443054e04 100644 --- a/codegen/src/test/resources/software/amazon/awssdk/codegen/poet/builder/test-sync-client-builder-class.java +++ b/codegen/src/test/resources/software/amazon/awssdk/codegen/poet/builder/test-sync-client-builder-class.java @@ -1,5 +1,6 @@ package software.amazon.awssdk.services.json; +import java.net.URI; import software.amazon.awssdk.annotations.Generated; import software.amazon.awssdk.annotations.SdkInternalApi; import software.amazon.awssdk.auth.token.credentials.SdkTokenProvider; @@ -31,9 +32,14 @@ public DefaultJsonClientBuilder tokenProvider(SdkTokenProvider tokenProvider) { protected final JsonClient buildClient() { SdkClientConfiguration clientConfiguration = super.syncClientConfiguration(); this.validateClientOptions(clientConfiguration); + URI endpointOverride = null; + if (clientConfiguration.option(SdkClientOption.ENDPOINT_OVERRIDDEN) != null + && Boolean.TRUE.equals(clientConfiguration.option(SdkClientOption.ENDPOINT_OVERRIDDEN))) { + endpointOverride = clientConfiguration.option(SdkClientOption.ENDPOINT); + } JsonServiceClientConfiguration serviceClientConfiguration = JsonServiceClientConfiguration.builder() .overrideConfiguration(overrideConfiguration()).region(clientConfiguration.option(AwsClientOption.AWS_REGION)) - .build(); + .endpointOverride(endpointOverride).build(); return new DefaultJsonClient(serviceClientConfiguration, clientConfiguration); } } diff --git a/codegen/src/test/resources/software/amazon/awssdk/codegen/poet/model/serviceclientconfiguration.java b/codegen/src/test/resources/software/amazon/awssdk/codegen/poet/model/serviceclientconfiguration.java index bdf37d454b3a..1220fcb9e0c0 100644 --- a/codegen/src/test/resources/software/amazon/awssdk/codegen/poet/model/serviceclientconfiguration.java +++ b/codegen/src/test/resources/software/amazon/awssdk/codegen/poet/model/serviceclientconfiguration.java @@ -1,5 +1,6 @@ package software.amazon.awssdk.services.jsonprotocoltests; +import java.net.URI; import software.amazon.awssdk.annotations.Generated; import software.amazon.awssdk.annotations.SdkPublicApi; import software.amazon.awssdk.awscore.AwsServiceClientConfiguration; @@ -30,11 +31,19 @@ public interface Builder extends AwsServiceClientConfiguration.Builder { /** * Configure the region */ + @Override Builder region(Region region); + /** + * Configure the endpointOverride + */ + @Override + Builder endpointOverride(URI endpointOverride); + /** * Configure the client override configuration */ + @Override Builder overrideConfiguration(ClientOverrideConfiguration clientOverrideConfiguration); } @@ -58,6 +67,12 @@ public Builder overrideConfiguration(ClientOverrideConfiguration clientOverrideC return this; } + @Override + public Builder endpointOverride(URI endpointOverride) { + this.endpointOverride = endpointOverride; + return this; + } + @Override public JsonProtocolTestsServiceClientConfiguration build() { return new JsonProtocolTestsServiceClientConfiguration(this); diff --git a/core/aws-core/src/main/java/software/amazon/awssdk/awscore/AwsServiceClientConfiguration.java b/core/aws-core/src/main/java/software/amazon/awssdk/awscore/AwsServiceClientConfiguration.java index 21cb86d0c539..30698fd6222a 100644 --- a/core/aws-core/src/main/java/software/amazon/awssdk/awscore/AwsServiceClientConfiguration.java +++ b/core/aws-core/src/main/java/software/amazon/awssdk/awscore/AwsServiceClientConfiguration.java @@ -15,6 +15,7 @@ package software.amazon.awssdk.awscore; +import java.net.URI; import java.util.Objects; import software.amazon.awssdk.annotations.SdkPublicApi; import software.amazon.awssdk.core.SdkServiceClientConfiguration; @@ -74,6 +75,12 @@ public interface Builder extends SdkServiceClientConfiguration.Builder { */ Builder region(Region region); + @Override + Builder overrideConfiguration(ClientOverrideConfiguration clientOverrideConfiguration); + + @Override + Builder endpointOverride(URI endpointOverride); + @Override AwsServiceClientConfiguration build(); } @@ -81,6 +88,7 @@ public interface Builder extends SdkServiceClientConfiguration.Builder { protected abstract static class BuilderImpl implements Builder { protected ClientOverrideConfiguration overrideConfiguration; protected Region region; + protected URI endpointOverride; protected BuilderImpl() { } @@ -88,19 +96,7 @@ protected BuilderImpl() { protected BuilderImpl(AwsServiceClientConfiguration awsServiceClientConfiguration) { this.overrideConfiguration = awsServiceClientConfiguration.overrideConfiguration(); this.region = awsServiceClientConfiguration.region(); - } - - - @Override - public Builder overrideConfiguration(ClientOverrideConfiguration clientOverrideConfiguration) { - this.overrideConfiguration = clientOverrideConfiguration; - return this; - } - - @Override - public Builder region(Region region) { - this.region = region; - return this; + this.endpointOverride = awsServiceClientConfiguration.endpointOverride().orElse(null); } @Override @@ -112,6 +108,11 @@ public final ClientOverrideConfiguration overrideConfiguration() { public final Region region() { return region; } + + @Override + public final URI endpointOverride() { + return endpointOverride; + } } } diff --git a/core/sdk-core/src/main/java/software/amazon/awssdk/core/SdkServiceClientConfiguration.java b/core/sdk-core/src/main/java/software/amazon/awssdk/core/SdkServiceClientConfiguration.java index d568b59b916a..26674d396b96 100644 --- a/core/sdk-core/src/main/java/software/amazon/awssdk/core/SdkServiceClientConfiguration.java +++ b/core/sdk-core/src/main/java/software/amazon/awssdk/core/SdkServiceClientConfiguration.java @@ -15,7 +15,9 @@ package software.amazon.awssdk.core; +import java.net.URI; import java.util.Objects; +import java.util.Optional; import software.amazon.awssdk.annotations.SdkPublicApi; import software.amazon.awssdk.core.client.config.ClientOverrideConfiguration; @@ -26,9 +28,11 @@ public abstract class SdkServiceClientConfiguration { private final ClientOverrideConfiguration overrideConfiguration; + private final URI endpointOverride; protected SdkServiceClientConfiguration(Builder builder) { this.overrideConfiguration = builder.overrideConfiguration(); + this.endpointOverride = builder.endpointOverride(); } /** @@ -40,6 +44,15 @@ public ClientOverrideConfiguration overrideConfiguration() { return this.overrideConfiguration; } + /** + * + * @return The configured endpoint override of the SdkClient. If the endpoint was not overridden, an empty Optional will be + * returned + */ + public Optional endpointOverride() { + return Optional.ofNullable(this.endpointOverride); + } + @Override public boolean equals(Object o) { if (this == o) { @@ -50,12 +63,15 @@ public boolean equals(Object o) { } SdkServiceClientConfiguration serviceClientConfiguration = (SdkServiceClientConfiguration) o; - return Objects.equals(overrideConfiguration, serviceClientConfiguration.overrideConfiguration()); + return Objects.equals(overrideConfiguration, serviceClientConfiguration.overrideConfiguration()) + && Objects.equals(endpointOverride, serviceClientConfiguration.endpointOverride().orElse(null)); } @Override public int hashCode() { - return overrideConfiguration != null ? overrideConfiguration.hashCode() : 0; + int result = overrideConfiguration != null ? overrideConfiguration.hashCode() : 0; + result = 31 * result + (endpointOverride != null ? endpointOverride.hashCode() : 0); + return result; } /** @@ -67,11 +83,21 @@ public interface Builder { */ ClientOverrideConfiguration overrideConfiguration(); + /** + * Return the endpoint override + */ + URI endpointOverride(); + /** * Configure the client override configuration */ Builder overrideConfiguration(ClientOverrideConfiguration clientOverrideConfiguration); + /** + * Configure the endpoint override + */ + Builder endpointOverride(URI endpointOverride); + /** * Build the service client configuration using the configuration on this builder */ diff --git a/test/codegen-generated-classes-test/src/test/java/software/amazon/awssdk/services/serviceclientconfiguration/ServiceClientConfigurationTest.java b/test/codegen-generated-classes-test/src/test/java/software/amazon/awssdk/services/serviceclientconfiguration/ServiceClientConfigurationTest.java index 1bdef415f5d8..6a0058400f27 100644 --- a/test/codegen-generated-classes-test/src/test/java/software/amazon/awssdk/services/serviceclientconfiguration/ServiceClientConfigurationTest.java +++ b/test/codegen-generated-classes-test/src/test/java/software/amazon/awssdk/services/serviceclientconfiguration/ServiceClientConfigurationTest.java @@ -17,6 +17,7 @@ import static org.assertj.core.api.Assertions.assertThat; +import java.net.URI; import java.time.Duration; import org.junit.jupiter.api.Test; import software.amazon.awssdk.core.client.config.ClientOverrideConfiguration; @@ -36,6 +37,26 @@ public void syncClient_serviceClientConfiguration_shouldReturnCorrectRegion() { assertThat(region).isEqualTo(Region.ME_SOUTH_1); } + @Test + public void syncClientWithEndpointOverride_serviceClientConfiguration_shouldReturnCorrectEndpointOverride() { + URI uri = URI.create("https://www.amazon.com/"); + ProtocolRestXmlClient client = ProtocolRestXmlClient.builder() + .endpointOverride(uri) + .build(); + + URI endpointOverride = client.serviceClientConfiguration().endpointOverride().orElse(null); + assertThat(endpointOverride).isEqualTo(uri); + } + + @Test + public void syncClientWithoutEndpointOverride_serviceClientConfiguration_shouldReturnEmptyOptional() { + ProtocolRestXmlClient client = ProtocolRestXmlClient.builder() + .build(); + + URI endpointOverride = client.serviceClientConfiguration().endpointOverride().orElse(null); + assertThat(endpointOverride).isNull(); + } + @Test public void syncClient_serviceClientConfiguration_shouldReturnCorrectClientOverrideConfigurationFields() { ClientOverrideConfiguration overrideConfiguration = ClientOverrideConfiguration.builder() @@ -80,6 +101,26 @@ public void asyncClient_serviceClientConfiguration_shouldReturnCorrectRegion() { assertThat(region).isEqualTo(Region.ME_SOUTH_1); } + @Test + public void asyncClientWithEndpointOverride_serviceClientConfiguration_shouldReturnCorrectEndpointOverride() { + URI uri = URI.create("https://www.amazon.com/"); + ProtocolRestXmlAsyncClient client = ProtocolRestXmlAsyncClient.builder() + .endpointOverride(uri) + .build(); + + URI endpointOverride = client.serviceClientConfiguration().endpointOverride().orElse(null); + assertThat(endpointOverride).isEqualTo(uri); + } + + @Test + public void asyncClientWithoutEndpointOverride_serviceClientConfiguration_shouldReturnEmptyOptional() { + ProtocolRestXmlAsyncClient client = ProtocolRestXmlAsyncClient.builder() + .build(); + + URI endpointOverride = client.serviceClientConfiguration().endpointOverride().orElse(null); + assertThat(endpointOverride).isNull(); + } + @Test public void asyncClient_serviceClientConfiguration_shouldReturnCorrectClientOverrideConfigurationFields() { ClientOverrideConfiguration overrideConfiguration = ClientOverrideConfiguration.builder()