2525import com .squareup .javapoet .ParameterizedTypeName ;
2626import com .squareup .javapoet .TypeName ;
2727import com .squareup .javapoet .TypeVariableName ;
28+ import com .squareup .javapoet .WildcardTypeName ;
2829import java .util .List ;
2930import java .util .Map ;
3031import java .util .Objects ;
3132import java .util .Optional ;
3233import java .util .Set ;
34+ import java .util .concurrent .CompletionException ;
3335import java .util .function .Consumer ;
3436import java .util .stream .Collectors ;
3537import javax .lang .model .element .Modifier ;
5153import software .amazon .awssdk .core .SdkClient ;
5254import software .amazon .awssdk .core .SdkPlugin ;
5355import software .amazon .awssdk .core .SdkRequest ;
56+ import software .amazon .awssdk .core .SelectedAuthScheme ;
5457import software .amazon .awssdk .core .client .config .ClientOverrideConfiguration ;
5558import software .amazon .awssdk .core .client .config .SdkClientConfiguration ;
5659import software .amazon .awssdk .core .client .config .SdkClientOption ;
60+ import software .amazon .awssdk .core .exception .SdkClientException ;
61+ import software .amazon .awssdk .core .interceptor .ExecutionAttributes ;
62+ import software .amazon .awssdk .core .interceptor .SdkInternalExecutionAttribute ;
5763import software .amazon .awssdk .core .retry .RetryMode ;
5864import software .amazon .awssdk .core .signer .Signer ;
65+ import software .amazon .awssdk .endpoints .Endpoint ;
5966import software .amazon .awssdk .http .auth .spi .scheme .AuthSchemeOption ;
6067import software .amazon .awssdk .retries .api .RetryStrategy ;
6168import software .amazon .awssdk .utils .AttributeMap ;
@@ -406,9 +413,6 @@ private static void addSimpleAuthSchemeResolution(MethodSpec.Builder builder,
406413 ClassName .get (Set .class ), awsClientOption );
407414 builder .beginControlFlow ("if (!$T.isNullOrEmpty(sigv4aRegionSet))" , CollectionUtils .class );
408415 builder .addStatement ("paramsBuilder.regionSet($T.create(sigv4aRegionSet))" , regionSet );
409- builder .nextControlFlow ("else" );
410- builder .addStatement ("paramsBuilder.regionSet($T.create(clientConfiguration.option($T.AWS_REGION).id()))" ,
411- regionSet , awsClientOption );
412416 builder .endControlFlow ();
413417 }
414418
@@ -422,7 +426,7 @@ private static void addEndpointBasedAuthSchemeResolution(MethodSpec.Builder buil
422426 ClassName paramsInterface = authSchemeSpecUtils .parametersInterfaceName ();
423427 ClassName awsClientOption = ClassName .get ("software.amazon.awssdk.awscore.client.config" , "AwsClientOption" );
424428 ClassName endpointParamsClass = endpointRulesSpecUtils .parametersClassName ();
425- ClassName resolverInterceptor = endpointRulesSpecUtils .resolverInterceptorName ();
429+ ClassName endpointResolverUtils = endpointRulesSpecUtils .endpointResolverUtilsName ();
426430 ClassName executionAttributesClass = ClassName .get ("software.amazon.awssdk.core.interceptor" , "ExecutionAttributes" );
427431 ClassName awsExecutionAttribute = ClassName .get ("software.amazon.awssdk.awscore" , "AwsExecutionAttribute" );
428432 ClassName sdkExecutionAttribute = ClassName .get ("software.amazon.awssdk.core.interceptor" , "SdkExecutionAttribute" );
@@ -447,7 +451,7 @@ private static void addEndpointBasedAuthSchemeResolution(MethodSpec.Builder buil
447451 sdkInternalExecutionAttribute , SdkClientOption .class );
448452
449453 builder .addStatement ("$T endpointParams = $T.ruleParams(request, executionAttributes)" ,
450- endpointParamsClass , resolverInterceptor );
454+ endpointParamsClass , endpointResolverUtils );
451455
452456 builder .addStatement ("$T.Builder paramsBuilder = $T.builder()" , paramsInterface , paramsInterface );
453457
@@ -467,6 +471,15 @@ private static void addEndpointBasedAuthSchemeResolution(MethodSpec.Builder buil
467471 builder .addStatement ("paramsBuilder.region(clientConfiguration.option($T.AWS_REGION))" , awsClientOption );
468472 }
469473
474+ if (authSchemeSpecUtils .hasSigV4aSupport ()) {
475+ ClassName regionSet = ClassName .get ("software.amazon.awssdk.http.auth.aws.signer" , "RegionSet" );
476+ builder .addStatement ("$T<String> sigv4aRegionSet = clientConfiguration.option($T.AWS_SIGV4A_SIGNING_REGION_SET)" ,
477+ ClassName .get (Set .class ), awsClientOption );
478+ builder .beginControlFlow ("if (!$T.isNullOrEmpty(sigv4aRegionSet))" , CollectionUtils .class );
479+ builder .addStatement ("paramsBuilder.regionSet($T.create(sigv4aRegionSet))" , regionSet );
480+ builder .endControlFlow ();
481+ }
482+
470483 ClassName paramsBuilderClass = authSchemeSpecUtils .parametersEndpointAwareDefaultImplName ().nestedClass ("Builder" );
471484 ClassName endpointProviderInterface = endpointRulesSpecUtils .providerInterfaceName ();
472485
@@ -482,4 +495,86 @@ private static void addEndpointBasedAuthSchemeResolution(MethodSpec.Builder buil
482495 builder .addStatement ("$T<$T> options = authSchemeProvider.resolveAuthScheme(paramsBuilder.build())" ,
483496 List .class , AuthSchemeOption .class );
484497 }
498+
499+ static MethodSpec resolveEndpointMethod (AuthSchemeSpecUtils authSchemeSpecUtils ,
500+ EndpointRulesSpecUtils endpointRulesSpecUtils ) {
501+ ClassName utilsClass = endpointRulesSpecUtils .endpointResolverUtilsName ();
502+ ClassName endpointParamsClass = endpointRulesSpecUtils .parametersClassName ();
503+ ClassName providerInterface = endpointRulesSpecUtils .providerInterfaceName ();
504+ ClassName awsEndpointProviderUtils = endpointRulesSpecUtils .sharedAwsEndpointProviderUtilsName ();
505+ ClassName awsEndpointAttribute = ClassName .get ("software.amazon.awssdk.awscore.endpoints" , "AwsEndpointAttribute" );
506+ ClassName endpointAuthScheme = ClassName .get ("software.amazon.awssdk.awscore.endpoints.authscheme" , "EndpointAuthScheme" );
507+
508+ MethodSpec .Builder b = MethodSpec .methodBuilder ("resolveEndpoint" )
509+ .addModifiers (PRIVATE )
510+ .returns (Endpoint .class )
511+ .addParameter (SdkRequest .class , "request" )
512+ .addParameter (ExecutionAttributes .class , "executionAttributes" )
513+ .addParameter (String .class , "operationName" );
514+
515+ b .addStatement ("$1T provider = ($1T) executionAttributes.getAttribute($2T.ENDPOINT_PROVIDER)" ,
516+ providerInterface , SdkInternalExecutionAttribute .class );
517+
518+ b .beginControlFlow ("try" );
519+ b .addStatement ("$T endpointParams = $T.ruleParams(request, executionAttributes)" ,
520+ endpointParamsClass , utilsClass );
521+ b .addStatement ("$T endpoint = provider.resolveEndpoint(endpointParams).join()" , Endpoint .class );
522+
523+ b .beginControlFlow ("if (!$T.disableHostPrefixInjection(executionAttributes))" , awsEndpointProviderUtils );
524+ b .addStatement ("$T hostPrefix = $T.hostPrefix(operationName, request)" ,
525+ ParameterizedTypeName .get (Optional .class , String .class ), utilsClass );
526+ b .beginControlFlow ("if (hostPrefix.isPresent())" );
527+ b .addStatement ("endpoint = $T.addHostPrefix(endpoint, hostPrefix.get())" , awsEndpointProviderUtils );
528+ b .endControlFlow ();
529+ b .endControlFlow ();
530+
531+ b .addStatement ("$T endpointAuthSchemes = endpoint.attribute($T.AUTH_SCHEMES)" ,
532+ ParameterizedTypeName .get (ClassName .get (List .class ), endpointAuthScheme ),
533+ awsEndpointAttribute );
534+ b .addStatement ("$T selectedAuthScheme = executionAttributes.getAttribute($T.SELECTED_AUTH_SCHEME)" ,
535+ ParameterizedTypeName .get (ClassName .get (SelectedAuthScheme .class ),
536+ WildcardTypeName .subtypeOf (Object .class )),
537+ SdkInternalExecutionAttribute .class );
538+ b .beginControlFlow ("if (endpointAuthSchemes != null && selectedAuthScheme != null)" );
539+ b .addStatement ("selectedAuthScheme = $T.authSchemeWithEndpointSignerProperties(endpointAuthSchemes, selectedAuthScheme)" ,
540+ utilsClass );
541+
542+ if (authSchemeSpecUtils .usesSigV4a () || authSchemeSpecUtils .generateEndpointBasedParams ()) {
543+ ClassName awsV4aAuthScheme = ClassName .get ("software.amazon.awssdk.http.auth.aws.scheme" , "AwsV4aAuthScheme" );
544+ ClassName awsV4aHttpSigner = ClassName .get ("software.amazon.awssdk.http.auth.aws.signer" , "AwsV4aHttpSigner" );
545+ ClassName regionSet = ClassName .get ("software.amazon.awssdk.http.auth.aws.signer" , "RegionSet" );
546+ ClassName authSchemeOption = ClassName .get ("software.amazon.awssdk.http.auth.spi.scheme" , "AuthSchemeOption" );
547+
548+ b .addComment ("Precedence of SigV4a RegionSet is set according to multi-auth SigV4a specifications" );
549+ b .beginControlFlow ("if (selectedAuthScheme.authSchemeOption().schemeId().equals($T.SCHEME_ID) "
550+ + "&& selectedAuthScheme.authSchemeOption().signerProperty($T.REGION_SET) == null)" ,
551+ awsV4aAuthScheme , awsV4aHttpSigner );
552+ b .addStatement ("$T optionBuilder = selectedAuthScheme.authSchemeOption().toBuilder()" ,
553+ authSchemeOption .nestedClass ("Builder" ));
554+ b .addStatement ("$1T rs = $1T.create(endpointParams.region().id())" , regionSet );
555+ b .addStatement ("optionBuilder.putSignerProperty($T.REGION_SET, rs)" , awsV4aHttpSigner );
556+ b .addStatement ("selectedAuthScheme = new $T(selectedAuthScheme.identity(), selectedAuthScheme.signer(), "
557+ + "optionBuilder.build())" , SelectedAuthScheme .class );
558+ b .endControlFlow ();
559+ }
560+
561+ b .addStatement ("executionAttributes.putAttribute($T.SELECTED_AUTH_SCHEME, selectedAuthScheme)" ,
562+ SdkInternalExecutionAttribute .class );
563+ b .endControlFlow ();
564+
565+ b .addStatement ("$T.setMetricValues(endpoint, executionAttributes)" , utilsClass );
566+
567+ b .addStatement ("return endpoint" );
568+
569+ b .nextControlFlow ("catch ($T e)" , CompletionException .class );
570+ b .addStatement ("$T cause = e.getCause()" , Throwable .class );
571+ b .beginControlFlow ("if (cause instanceof $T)" , SdkClientException .class );
572+ b .addStatement ("throw ($T) cause" , SdkClientException .class );
573+ b .endControlFlow ();
574+ b .addStatement ("throw $T.create($S + cause.getMessage(), cause)" ,
575+ SdkClientException .class , "Endpoint resolution failed: " );
576+ b .endControlFlow ();
577+
578+ return b .build ();
579+ }
485580}
0 commit comments