in codegen/src/main/java/software/amazon/awssdk/codegen/poet/builder/BaseClientBuilderClass.java [336:533]
private MethodSpec finalizeServiceConfigurationMethod() {
String requestHandlerDirectory = Utils.packageToDirectory(model.getMetadata().getFullClientPackageName());
String requestHandlerPath = String.format("%s/execution.interceptors", requestHandlerDirectory);
MethodSpec.Builder builder = MethodSpec.methodBuilder("finalizeServiceConfiguration")
.addAnnotation(Override.class)
.addModifiers(PROTECTED, FINAL)
.returns(SdkClientConfiguration.class)
.addParameter(SdkClientConfiguration.class, "config");
// Initialize configuration values
builder.addStatement("$T endpointInterceptors = new $T<>()",
ParameterizedTypeName.get(List.class, ExecutionInterceptor.class),
ArrayList.class);
List<ClassName> builtInInterceptors = new ArrayList<>();
if (authSchemeSpecUtils.useSraAuth()) {
builtInInterceptors.add(authSchemeSpecUtils.authSchemeInterceptor());
}
builtInInterceptors.add(endpointRulesSpecUtils.resolverInterceptorName());
builtInInterceptors.add(endpointRulesSpecUtils.requestModifierInterceptorName());
for (String interceptor : model.getCustomizationConfig().getInterceptors()) {
builtInInterceptors.add(ClassName.bestGuess(interceptor));
}
for (ClassName interceptor : builtInInterceptors) {
builder.addStatement("endpointInterceptors.add(new $T())", interceptor);
}
builder.addCode("$1T interceptorFactory = new $1T();\n", ClasspathInterceptorChainFactory.class)
.addCode("$T<$T> interceptors = interceptorFactory.getInterceptors($S);\n",
List.class, ExecutionInterceptor.class, requestHandlerPath);
builder.addStatement("$T additionalInterceptors = new $T<>()",
ParameterizedTypeName.get(List.class,
ExecutionInterceptor.class),
ArrayList.class);
builder.addStatement("interceptors = $T.mergeLists(endpointInterceptors, interceptors)",
CollectionUtils.class);
builder.addStatement("interceptors = $T.mergeLists(interceptors, additionalInterceptors)",
CollectionUtils.class);
builder.addCode("interceptors = $T.mergeLists(interceptors, config.option($T.EXECUTION_INTERCEPTORS));\n",
CollectionUtils.class, SdkClientOption.class);
if (model.getEndpointOperation().isPresent()) {
builder.beginControlFlow("if (!endpointDiscoveryEnabled)")
.addStatement("$1T chain = new $1T(config)", DefaultEndpointDiscoveryProviderChain.class)
.addStatement("endpointDiscoveryEnabled = chain.resolveEndpointDiscovery()")
.endControlFlow();
}
String clientConfigClassName = model.getCustomizationConfig().getServiceConfig().getClassName();
if (StringUtils.isNotBlank(clientConfigClassName)) {
mergeServiceConfiguration(builder, clientConfigClassName);
}
if (model.getCustomizationConfig().useGlobalEndpoint()) {
builder.addStatement("$1T globalEndpointResolver = new $1T(config)",
ClassName.get("software.amazon.awssdk.services.s3.internal.endpoints",
"UseGlobalEndpointResolver"));
}
if (model.getCustomizationConfig().useS3ExpressSessionAuth()) {
builder.addStatement("$1T useS3ExpressAuthResolver = new $1T(config)",
ClassName.get("software.amazon.awssdk.services.s3.internal.s3express",
"UseS3ExpressAuthResolver"));
CodeBlock key = CodeBlock.of("$T.DISABLE_S3_EXPRESS_SESSION_AUTH",
endpointRulesSpecUtils.clientContextParamsName());
builder.beginControlFlow("if (clientContextParams.get($L) == null)",
key);
builder.addStatement("clientContextParams.put($L, !useS3ExpressAuthResolver.resolve())", key);
builder.endControlFlow();
}
// Update configuration
builder.addStatement("$T builder = config.toBuilder()", SdkClientConfiguration.Builder.class);
builder.addCode("builder.lazyOption($T.IDENTITY_PROVIDERS, c -> {", SdkClientOption.class)
.addStatement("$1T.Builder result = $1T.builder()", IdentityProviders.class);
if (AuthUtils.usesBearerAuth(model)) {
builder.addStatement("$T<?> tokenIdentityProvider = c.get($T.TOKEN_IDENTITY_PROVIDER)",
IdentityProvider.class, AwsClientOption.class);
builder.beginControlFlow("if (tokenIdentityProvider != null)");
builder.addStatement("result.putIdentityProvider(tokenIdentityProvider)");
builder.endControlFlow();
}
if (AuthUtils.usesAwsAuth(model)) {
builder.addStatement("$T<?> credentialsIdentityProvider = c.get($T.CREDENTIALS_IDENTITY_PROVIDER)",
IdentityProvider.class, AwsClientOption.class);
builder.beginControlFlow("if (credentialsIdentityProvider != null)", AwsClientOption.class);
builder.addStatement("result.putIdentityProvider(credentialsIdentityProvider)");
builder.endControlFlow();
}
builder.addStatement("return result.build()")
.addCode("});");
builder.addStatement("builder.option($1T.EXECUTION_INTERCEPTORS, interceptors)", SdkClientOption.class);
if (model.getCustomizationConfig().getServiceConfig().hasDualstackProperty()) {
// NOTE: usage of serviceConfigBuilder and not finalServiceConfig is intentional. We need the nullable boolean here
// to ensure fallback resolution of the dualstack configuration if dualstack was not explicitly configured on
// serviceConfigBuilder; the service configuration classes (e.g. S3Configuration) return primitive booleans that
// have a default when not present.
builder.addStatement("builder.option($T.DUALSTACK_ENDPOINT_ENABLED, serviceConfigBuilder.dualstackEnabled())",
AwsClientOption.class);
}
if (model.getCustomizationConfig().getServiceConfig().hasFipsProperty()) {
builder.addStatement("builder.option($T.FIPS_ENDPOINT_ENABLED, finalServiceConfig.fipsModeEnabled())",
AwsClientOption.class);
}
if (model.getEndpointOperation().isPresent()) {
builder.addStatement("builder.option($T.ENDPOINT_DISCOVERY_ENABLED, endpointDiscoveryEnabled)\n",
SdkClientOption.class);
}
if (StringUtils.isNotBlank(model.getCustomizationConfig().getCustomRetryStrategy())) {
builder.addStatement("builder.option($1T.RETRY_STRATEGY, $2T.resolveRetryStrategy(config))",
SdkClientOption.class,
PoetUtils.classNameFromFqcn(model.getCustomizationConfig().getCustomRetryStrategy()));
}
if (StringUtils.isNotBlank(model.getCustomizationConfig().getCustomRetryPolicy())) {
builder.beginControlFlow("if (builder.option($T.RETRY_STRATEGY) == null)", SdkClientOption.class);
builder.addStatement("builder.option($1T.RETRY_POLICY, $2T.resolveRetryPolicy(config))",
SdkClientOption.class,
PoetUtils.classNameFromFqcn(model.getCustomizationConfig().getCustomRetryPolicy()));
builder.endControlFlow();
}
if (StringUtils.isNotBlank(clientConfigClassName)) {
builder.addStatement("builder.option($T.SERVICE_CONFIGURATION, finalServiceConfig)", SdkClientOption.class);
}
if (model.getCustomizationConfig().useGlobalEndpoint()) {
builder.addStatement("builder.option($1T.USE_GLOBAL_ENDPOINT, "
+ "globalEndpointResolver.resolve(config.option($1T.AWS_REGION)))", AwsClientOption.class);
}
if (hasClientContextParams() || endpointRulesSpecUtils.useS3Express()) {
builder.addStatement("builder.option($T.CLIENT_CONTEXT_PARAMS, clientContextParams.build())", SdkClientOption.class);
}
if (endpointParamsKnowledgeIndex.hasAccountIdEndpointModeBuiltIn()) {
builder.addStatement("builder.option($T.$L, resolveAccountIdEndpointMode(config))",
AwsClientOption.class, model.getNamingStrategy().getEnumValueName("accountIdEndpointMode"));
}
String serviceNameForEnvVar = model.getNamingStrategy().getServiceNameForEnvironmentVariables();
String serviceNameForSystemProperty = model.getNamingStrategy().getServiceNameForSystemProperties();
String serviceNameForProfileFile = model.getNamingStrategy().getServiceNameForProfileFile();
builder.addCode("builder.lazyOptionIfAbsent($T.CLIENT_ENDPOINT_PROVIDER, c ->", SdkClientOption.class)
.addCode(" $T.builder()", AwsClientEndpointProvider.class)
.addCode(" .serviceEndpointOverrideEnvironmentVariable($S)", "AWS_ENDPOINT_URL_" + serviceNameForEnvVar)
.addCode(" .serviceEndpointOverrideSystemProperty($S)", "aws.endpointUrl" + serviceNameForSystemProperty)
.addCode(" .serviceProfileProperty($S)", serviceNameForProfileFile)
.addCode(" .serviceEndpointPrefix(serviceEndpointPrefix())")
.addCode(" .defaultProtocol($S)", "https")
.addCode(" .region(c.get($T.AWS_REGION))", AwsClientOption.class)
.addCode(" .profileFile(c.get($T.PROFILE_FILE_SUPPLIER))", SdkClientOption.class)
.addCode(" .profileName(c.get($T.PROFILE_NAME))", SdkClientOption.class)
.addCode(" .putAdvancedOption($T.DEFAULT_S3_US_EAST_1_REGIONAL_ENDPOINT,", ServiceMetadataAdvancedOption.class)
.addCode(" c.get($T.DEFAULT_S3_US_EAST_1_REGIONAL_ENDPOINT))", ServiceMetadataAdvancedOption.class)
.addCode(" .dualstackEnabled(c.get($T.DUALSTACK_ENDPOINT_ENABLED))", AwsClientOption.class)
.addCode(" .fipsEnabled(c.get($T.FIPS_ENDPOINT_ENABLED))", AwsClientOption.class)
.addCode(" .build());");
if (model.getMetadata().isJsonProtocol()) {
if (model.getCustomizationConfig().getEnableFastUnmarshaller()) {
builder.addStatement("builder.option($1T.ENABLE_FAST_UNMARSHALLER, true)",
SdkClientJsonProtocolAdvancedOption.class);
}
}
if (hasRequestAlgorithmMember(model) || hasResponseAlgorithms(model)) {
builder.addStatement("$T clientConfig = config", SdkClientConfiguration.class);
if (hasRequestAlgorithmMember(model)) {
builder.addStatement("builder.lazyOption($T.REQUEST_CHECKSUM_CALCULATION, "
+ "c -> resolveRequestChecksumCalculation(clientConfig))", SdkClientOption.class);
}
if (hasResponseAlgorithms(model)) {
builder.addStatement("builder.lazyOption($T.RESPONSE_CHECKSUM_VALIDATION, "
+ "c -> resolveResponseChecksumValidation(clientConfig))", SdkClientOption.class);
}
}
builder.addStatement("return builder.build()");
return builder.build();
}