From 70aacf5edb128fa77d343f83e562cf01fef8b870 Mon Sep 17 00:00:00 2001 From: Ian Botsford <83236726+ianbotsf@users.noreply.github.com> Date: Thu, 13 Feb 2025 01:06:19 +0000 Subject: [PATCH] fix: favor endpointUrl over endpoint discovery when provided --- .../e7d8178c-4211-443d-b4d9-44d7019aefd1.json | 8 ++++ .../discovery/EndpointDiscovererGenerator.kt | 37 +++++++++++-------- .../EndpointDiscovererGeneratorTest.kt | 30 ++++++++------- 3 files changed, 47 insertions(+), 28 deletions(-) create mode 100644 .changes/e7d8178c-4211-443d-b4d9-44d7019aefd1.json diff --git a/.changes/e7d8178c-4211-443d-b4d9-44d7019aefd1.json b/.changes/e7d8178c-4211-443d-b4d9-44d7019aefd1.json new file mode 100644 index 0000000000..51864abe9b --- /dev/null +++ b/.changes/e7d8178c-4211-443d-b4d9-44d7019aefd1.json @@ -0,0 +1,8 @@ +{ + "id": "e7d8178c-4211-443d-b4d9-44d7019aefd1", + "type": "bugfix", + "description": "Favor `endpointUrl` over endpoint discovery when provided", + "issues": [ + "https://github.com/awslabs/aws-sdk-kotlin/issues/1413" + ] +} \ No newline at end of file diff --git a/codegen/smithy-kotlin-codegen/src/main/kotlin/software/amazon/smithy/kotlin/codegen/rendering/endpoints/discovery/EndpointDiscovererGenerator.kt b/codegen/smithy-kotlin-codegen/src/main/kotlin/software/amazon/smithy/kotlin/codegen/rendering/endpoints/discovery/EndpointDiscovererGenerator.kt index c492cd743d..73b6e434da 100644 --- a/codegen/smithy-kotlin-codegen/src/main/kotlin/software/amazon/smithy/kotlin/codegen/rendering/endpoints/discovery/EndpointDiscovererGenerator.kt +++ b/codegen/smithy-kotlin-codegen/src/main/kotlin/software/amazon/smithy/kotlin/codegen/rendering/endpoints/discovery/EndpointDiscovererGenerator.kt @@ -13,6 +13,7 @@ import software.amazon.smithy.kotlin.codegen.model.buildSymbol import software.amazon.smithy.kotlin.codegen.model.expectShape import software.amazon.smithy.kotlin.codegen.model.expectTrait import software.amazon.smithy.kotlin.codegen.rendering.endpoints.EndpointResolverAdapterGenerator +import software.amazon.smithy.kotlin.codegen.rendering.endpoints.SdkEndpointBuiltinIntegration import software.amazon.smithy.model.shapes.OperationShape import software.amazon.smithy.model.shapes.ServiceShape @@ -80,21 +81,27 @@ class EndpointDiscovererGenerator(private val ctx: CodegenContext, private val d EndpointResolverAdapterGenerator.getSymbol(ctx.settings), RuntimeTypes.HttpClient.Operation.EndpointResolver, ) { - write("val identity = request.identity") - write( - """require(identity is #T) { "Endpoint discovery requires AWS credentials" }""", - RuntimeTypes.Auth.Credentials.AwsCredentials.Credentials, - ) - write("") - write("val cacheKey = DiscoveryParams(client.config.region, identity.accessKeyId)") - write("request.context[discoveryParamsKey] = cacheKey") - write("val discoveredHost = cache.get(cacheKey) { discoverHost(client) }") - write("") - write("val originalEndpoint = delegate.resolve(request)") - withBlock("#T(", ")", RuntimeTypes.SmithyClient.Endpoints.Endpoint) { - write("originalEndpoint.uri.copy { host = discoveredHost },") - write("originalEndpoint.headers,") - write("originalEndpoint.attributes,") + // Backported from https://github.com/smithy-lang/smithy-kotlin/pull/1221; replace when merging v1.5 to main + withBlock("if (client.config.#L == null) {", "}", SdkEndpointBuiltinIntegration.EndpointUrlProp.propertyName) { + write("val identity = request.identity") + write( + """require(identity is #T) { "Endpoint discovery requires AWS credentials" }""", + RuntimeTypes.Auth.Credentials.AwsCredentials.Credentials, + ) + write("") + write("val cacheKey = DiscoveryParams(client.config.region, identity.accessKeyId)") + write("request.context[discoveryParamsKey] = cacheKey") + write("val discoveredHost = cache.get(cacheKey) { discoverHost(client) }") + write("") + write("val originalEndpoint = delegate.resolve(request)") + withBlock("#T(", ")", RuntimeTypes.SmithyClient.Endpoints.Endpoint) { + write("originalEndpoint.uri.copy { host = discoveredHost },") + write("originalEndpoint.headers,") + write("originalEndpoint.attributes,") + } + // If user manually specifies endpointUrl, skip endpoint discovery + closeAndOpenBlock("} else {") + write("delegate.resolve(request)") } } } diff --git a/codegen/smithy-kotlin-codegen/src/test/kotlin/software/amazon/smithy/kotlin/codegen/rendering/endpoints/discovery/EndpointDiscovererGeneratorTest.kt b/codegen/smithy-kotlin-codegen/src/test/kotlin/software/amazon/smithy/kotlin/codegen/rendering/endpoints/discovery/EndpointDiscovererGeneratorTest.kt index b67c51d57a..37b9e6a900 100644 --- a/codegen/smithy-kotlin-codegen/src/test/kotlin/software/amazon/smithy/kotlin/codegen/rendering/endpoints/discovery/EndpointDiscovererGeneratorTest.kt +++ b/codegen/smithy-kotlin-codegen/src/test/kotlin/software/amazon/smithy/kotlin/codegen/rendering/endpoints/discovery/EndpointDiscovererGeneratorTest.kt @@ -37,19 +37,23 @@ class EndpointDiscovererGeneratorTest { actual.shouldContainOnlyOnceWithDiff( """ internal fun asEndpointResolver(client: TestClient, delegate: EndpointResolverAdapter) = EndpointResolver { request -> - val identity = request.identity - require(identity is Credentials) { "Endpoint discovery requires AWS credentials" } - - val cacheKey = DiscoveryParams(client.config.region, identity.accessKeyId) - request.context[discoveryParamsKey] = cacheKey - val discoveredHost = cache.get(cacheKey) { discoverHost(client) } - - val originalEndpoint = delegate.resolve(request) - Endpoint( - originalEndpoint.uri.copy { host = discoveredHost }, - originalEndpoint.headers, - originalEndpoint.attributes, - ) + if (client.config.endpointUrl == null) { + val identity = request.identity + require(identity is Credentials) { "Endpoint discovery requires AWS credentials" } + + val cacheKey = DiscoveryParams(client.config.region, identity.accessKeyId) + request.context[discoveryParamsKey] = cacheKey + val discoveredHost = cache.get(cacheKey) { discoverHost(client) } + + val originalEndpoint = delegate.resolve(request) + Endpoint( + originalEndpoint.uri.copy { host = discoveredHost }, + originalEndpoint.headers, + originalEndpoint.attributes, + ) + } else { + delegate.resolve(request) + } } """.formatForTest(), )