in codegen/src/main/java/software/amazon/awssdk/codegen/poet/rules/EndpointResolverInterceptorSpec.java [177:270]
private MethodSpec modifyRequestMethod(String endpointAuthSchemeStrategyFieldName) {
MethodSpec.Builder b = MethodSpec.methodBuilder("modifyRequest")
.addModifiers(Modifier.PUBLIC)
.addAnnotation(Override.class)
.returns(SdkRequest.class)
.addParameter(Context.ModifyRequest.class, "context")
.addParameter(ExecutionAttributes.class, "executionAttributes");
String providerVar = "provider";
b.addStatement("$T result = context.request()", SdkRequest.class);
// We skip resolution if the source of the endpoint is the endpoint discovery call
b.beginControlFlow("if ($1T.endpointIsDiscovered(executionAttributes))",
endpointRulesSpecUtils.rulesRuntimeClassName("AwsEndpointProviderUtils"));
b.addStatement("return result");
b.endControlFlow();
b.addStatement("$1T $2N = ($1T) executionAttributes.getAttribute($3T.ENDPOINT_PROVIDER)",
endpointRulesSpecUtils.providerInterfaceName(), providerVar, SdkInternalExecutionAttribute.class);
b.beginControlFlow("try");
b.addStatement("long resolveEndpointStart = $T.nanoTime()", System.class);
b.addStatement("$T endpointParams = ruleParams(result, executionAttributes)",
endpointRulesSpecUtils.parametersClassName());
b.addStatement("$T endpoint = $N.resolveEndpoint(endpointParams).join()",
Endpoint.class, providerVar);
b.addStatement("$1T resolveEndpointDuration = $1T.ofNanos($2T.nanoTime() - resolveEndpointStart)", Duration.class,
System.class);
b.addStatement("$T metricCollector = executionAttributes.getOptionalAttribute($T.API_CALL_METRIC_COLLECTOR)",
ParameterizedTypeName.get(Optional.class, MetricCollector.class), SdkExecutionAttribute.class);
b.addStatement("metricCollector.ifPresent(mc -> mc.reportMetric($T.ENDPOINT_RESOLVE_DURATION, resolveEndpointDuration))",
CoreMetric.class);
b.beginControlFlow("if (!$T.disableHostPrefixInjection(executionAttributes))",
endpointRulesSpecUtils.rulesRuntimeClassName("AwsEndpointProviderUtils"));
b.addStatement("$T hostPrefix = hostPrefix(executionAttributes.getAttribute($T.OPERATION_NAME), result)",
ParameterizedTypeName.get(Optional.class, String.class), SdkExecutionAttribute.class);
b.beginControlFlow("if (hostPrefix.isPresent())");
b.addStatement("endpoint = $T.addHostPrefix(endpoint, hostPrefix.get())",
endpointRulesSpecUtils.rulesRuntimeClassName("AwsEndpointProviderUtils"));
b.endControlFlow();
b.endControlFlow();
// If the endpoint resolver returns auth settings, use them as signer properties.
// This effectively works to set the preSRA Signer ExecutionAttributes, so it is not conditional on useSraAuth.
b.addStatement("$T<$T> endpointAuthSchemes = endpoint.attribute($T.AUTH_SCHEMES)",
List.class, EndpointAuthScheme.class, AwsEndpointAttribute.class);
b.addStatement("$T<?> selectedAuthScheme = executionAttributes.getAttribute($T.SELECTED_AUTH_SCHEME)",
SelectedAuthScheme.class, SdkInternalExecutionAttribute.class);
b.beginControlFlow("if (endpointAuthSchemes != null && selectedAuthScheme != null)");
b.addStatement("selectedAuthScheme = authSchemeWithEndpointSignerProperties(endpointAuthSchemes, selectedAuthScheme)");
if (multiAuthSigv4a || legacyAuthFromEndpointRulesService) {
b.addComment("Precedence of SigV4a RegionSet is set according to multi-auth SigV4a specifications");
b.beginControlFlow("if(selectedAuthScheme.authSchemeOption().schemeId().equals($T.SCHEME_ID) "
+ "&& selectedAuthScheme.authSchemeOption().signerProperty($T.REGION_SET) == null)",
AwsV4aAuthScheme.class, AwsV4aHttpSigner.class);
b.addStatement("$T optionBuilder = selectedAuthScheme.authSchemeOption().toBuilder()",
AuthSchemeOption.Builder.class);
b.addStatement("$T regionSet = $T.create(endpointParams.region().id())",
RegionSet.class, RegionSet.class);
b.addStatement("optionBuilder.putSignerProperty($T.REGION_SET, regionSet)", AwsV4aHttpSigner.class);
b.addStatement("selectedAuthScheme = new $T(selectedAuthScheme.identity(), selectedAuthScheme.signer(), "
+ "optionBuilder.build())", SelectedAuthScheme.class);
b.endControlFlow();
}
b.addStatement("executionAttributes.putAttribute($T.SELECTED_AUTH_SCHEME, selectedAuthScheme)",
SdkInternalExecutionAttribute.class);
b.endControlFlow();
// For pre SRA client, use Signer as determined by endpoint resolved auth scheme
if (!useSraAuth) {
b.beginControlFlow("if (endpointAuthSchemes != null)");
b.addStatement("$T chosenAuthScheme = $N.chooseAuthScheme(endpointAuthSchemes)", EndpointAuthScheme.class,
endpointAuthSchemeStrategyFieldName);
b.addStatement("$T<$T> signerProvider = signerProvider(chosenAuthScheme)", Supplier.class, Signer.class);
b.addStatement("result = $T.overrideSignerIfNotOverridden(result, executionAttributes, signerProvider)",
SignerOverrideUtils.class);
b.endControlFlow();
}
b.addStatement("executionAttributes.putAttribute(SdkInternalExecutionAttribute.RESOLVED_ENDPOINT, endpoint)");
b.addStatement("return result");
b.endControlFlow();
b.beginControlFlow("catch ($T e)", CompletionException.class);
b.addStatement("$T cause = e.getCause()", Throwable.class);
b.beginControlFlow("if (cause instanceof $T)", SdkClientException.class);
b.addStatement("throw ($T) cause", SdkClientException.class);
b.endControlFlow();
b.beginControlFlow("else");
b.addStatement("throw $T.create($S, cause)", SdkClientException.class, "Endpoint resolution failed");
b.endControlFlow();
b.endControlFlow();
return b.build();
}