in plugins/core/core/src/migration/software/aws/toolkits/core/ToolkitClientManager.kt [148:258]
protected open fun <T : SdkClient> constructAwsClient(
sdkClass: KClass<T>,
credProvider: AwsCredentialsProvider? = null,
tokenProvider: SdkTokenProvider? = null,
region: Region,
endpointOverride: String? = null,
clientCustomizer: ToolkitClientCustomizer? = null,
): T {
checkNotNull(credProvider ?: tokenProvider) { "Either a credential provider or a bearer token provider must be provided" }
val builderMethod = sdkClass.java.methods.find {
it.name == "builder" && Modifier.isStatic(it.modifiers) && Modifier.isPublic(it.modifiers)
} ?: throw IllegalArgumentException("Expected service interface to have a public static `builder()` method.")
val builder = builderMethod.invoke(null) as AwsDefaultClientBuilder<*, *>
@Suppress("UNCHECKED_CAST")
return builder
.region(region)
.apply {
if (this is SdkSyncClientBuilder<*, *>) {
// async clients use CRT, and keeps trying to shut down our apache client even though it doesn't respect our client settings
// so only set this for sync clients
httpClient(sdkHttpClient())
}
val clientOverrideConfig = ClientOverrideConfiguration.builder()
if (credProvider != null) {
credentialsProvider(credProvider)
}
if (tokenProvider != null) {
val tokenMethod = builderMethod.returnType.methods.find {
it.name == "tokenProvider" &&
it.parameterCount == 1 &&
it.parameters[0].type.name == "software.amazon.awssdk.auth.token.credentials.SdkTokenProvider"
}
if (tokenMethod == null) {
LOG.warn { "Ignoring bearer provider parameter for ${sdkClass.qualifiedName} since it's not a supported client attribute" }
} else {
tokenMethod.invoke(this, tokenProvider)
clientOverrideConfig.nullDefaultProfileFile()
// TODO: why do we need this?
clientOverrideConfig.putAdvancedOption(SdkAdvancedClientOption.SIGNER, BearerTokenSigner())
}
}
clientOverrideConfig.addExecutionInterceptor(object : ExecutionInterceptor {
override fun modifyRequest(
context: Context.ModifyRequest,
executionAttributes: ExecutionAttributes,
): SdkRequest {
val request = context.request()
if (request !is AwsRequest) {
return request
}
val clientType = executionAttributes.getAttribute(AwsExecutionAttribute.CLIENT_TYPE)
val sdkClient = executionAttributes.getAttribute(SdkInternalExecutionAttribute.SDK_CLIENT)
val serviceClientConfiguration = sdkClient.serviceClientConfiguration()
val retryMode = serviceClientConfiguration.overrideConfiguration().retryMode().orElse(RetryMode.defaultRetryMode())
val toolkitUserAgent = userAgent()
val requestUserAgent = ApplyUserAgentStage.resolveClientUserAgent(
toolkitUserAgent,
null,
clientType,
null,
null,
retryMode.toString().lowercase()
)
val overrideConfiguration = request.overrideConfiguration()
.map { config ->
config.toBuilder()
.putHeader(HEADER_USER_AGENT, requestUserAgent)
.build()
}
.orElseGet {
AwsRequestOverrideConfiguration.builder()
.putHeader(HEADER_USER_AGENT, requestUserAgent)
.build()
}
return request.toBuilder()
.overrideConfiguration(overrideConfiguration)
.build()
}
})
clientOverrideConfig.let { configuration ->
configuration.retryStrategy(RetryMode.STANDARD)
}
endpointOverride?.let {
endpointOverride(URI.create(it))
}
globalClientCustomizer(credProvider, tokenProvider, region.id(), this, clientOverrideConfig)
clientCustomizer?.let {
it.customize(credProvider, tokenProvider, region.id(), this, clientOverrideConfig)
}
// TODO: ban overrideConfiguration outside of here
overrideConfiguration(clientOverrideConfig.build())
}
.build() as T
}