All Downloads are FREE. Search and download functionalities are using the official Maven repository.

commonMain.aws.sdk.kotlin.services.timestreamquery.endpoints.TimestreamQueryEndpointDiscoverer.kt Maven / Gradle / Ivy

There is a newer version: 1.3.76
Show newest version
// Code generated by smithy-kotlin-codegen. DO NOT EDIT!

package aws.sdk.kotlin.services.timestreamquery.endpoints

import aws.sdk.kotlin.services.timestreamquery.TimestreamQueryClient
import aws.sdk.kotlin.services.timestreamquery.endpoints.internal.EndpointResolverAdapter
import aws.smithy.kotlin.runtime.auth.awscredentials.Credentials
import aws.smithy.kotlin.runtime.client.endpoints.Endpoint
import aws.smithy.kotlin.runtime.client.endpoints.EndpointProviderException
import aws.smithy.kotlin.runtime.collections.AttributeKey
import aws.smithy.kotlin.runtime.collections.ReadThroughCache
import aws.smithy.kotlin.runtime.http.operation.EndpointResolver
import aws.smithy.kotlin.runtime.net.Host
import aws.smithy.kotlin.runtime.operation.ExecutionContext
import aws.smithy.kotlin.runtime.time.Clock
import aws.smithy.kotlin.runtime.time.Instant
import aws.smithy.kotlin.runtime.util.ExpiringValue
import kotlin.time.Duration.Companion.minutes

/**
 * A class which looks up specific endpoints for Timestream Query calls via the `describeEndpoints`
 * API. These unique endpoints are cached as appropriate to avoid unnecessary latency in subsequent
 * calls.
 */
public class TimestreamQueryEndpointDiscoverer {
    private val cache = ReadThroughCache(10.minutes, Clock.System)

    internal fun asEndpointResolver(client: TimestreamQueryClient, 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,
        )
    }

    private suspend fun discoverHost(client: TimestreamQueryClient): ExpiringValue =
        client.describeEndpoints()
            .endpoints
            ?.map { ep -> ExpiringValue(
                Host.parse(ep.address!!),
                Instant.now() + ep.cachePeriodInMinutes.minutes,
            )}
            ?.firstOrNull()
            ?: throw EndpointProviderException("Unable to discover any endpoints when invoking describeEndpoints!")

    internal suspend fun invalidate(context: ExecutionContext) {
        context.getOrNull(discoveryParamsKey)?.let { cache.invalidate(it) }
    }
}

private val discoveryParamsKey = AttributeKey("DiscoveryParams")
private data class DiscoveryParams(private val region: String?, private val identity: String)




© 2015 - 2024 Weber Informatics LLC | Privacy Policy