Skip to content

Commit 87d0960

Browse files
committed
Move endpoint resolution from interceptors to pipeline stage
1 parent bfc51a7 commit 87d0960

66 files changed

Lines changed: 3309 additions & 1638 deletions

File tree

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

codegen/src/main/java/software/amazon/awssdk/codegen/emitters/tasks/AuthSchemeGeneratorTasks.java

Lines changed: 0 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,6 @@
2020
import software.amazon.awssdk.codegen.emitters.GeneratorTask;
2121
import software.amazon.awssdk.codegen.emitters.GeneratorTaskParams;
2222
import software.amazon.awssdk.codegen.emitters.PoetGeneratorTask;
23-
import software.amazon.awssdk.codegen.poet.auth.scheme.AuthSchemeInterceptorSpec;
2423
import software.amazon.awssdk.codegen.poet.auth.scheme.AuthSchemeParamsSpec;
2524
import software.amazon.awssdk.codegen.poet.auth.scheme.AuthSchemeProviderSpec;
2625
import software.amazon.awssdk.codegen.poet.auth.scheme.AuthSchemeSpecUtils;
@@ -85,10 +84,6 @@ private GeneratorTask generateEndpointAwareAuthSchemeParams() {
8584

8685
}
8786

88-
private GeneratorTask generateAuthSchemeInterceptor() {
89-
return new PoetGeneratorTask(authSchemeInternalDir(), model.getFileHeader(), new AuthSchemeInterceptorSpec(model));
90-
}
91-
9287
private String authSchemeDir() {
9388
return generatorTaskParams.getPathProvider().getAuthSchemeDirectory();
9489
}

codegen/src/main/java/software/amazon/awssdk/codegen/emitters/tasks/EndpointProviderTasks.java

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -32,9 +32,8 @@
3232
import software.amazon.awssdk.codegen.poet.rules.EndpointProviderInterfaceSpec;
3333
import software.amazon.awssdk.codegen.poet.rules.EndpointProviderSpec;
3434
import software.amazon.awssdk.codegen.poet.rules.EndpointProviderTestSpec;
35-
import software.amazon.awssdk.codegen.poet.rules.EndpointResolverInterceptorSpec;
35+
import software.amazon.awssdk.codegen.poet.rules.EndpointResolverUtilsSpec;
3636
import software.amazon.awssdk.codegen.poet.rules.EndpointRulesClientTestSpec;
37-
import software.amazon.awssdk.codegen.poet.rules.RequestEndpointInterceptorSpec;
3837
import software.amazon.awssdk.codegen.poet.rules2.EndpointProviderSpec2;
3938

4039
public final class EndpointProviderTasks extends BaseGeneratorTasks {
@@ -103,8 +102,7 @@ private boolean shouldGenerateCompiledEndpointRules() {
103102

104103
private Collection<GeneratorTask> generateInterceptors() {
105104
return Arrays.asList(
106-
new PoetGeneratorTask(endpointRulesInternalDir(), model.getFileHeader(), new EndpointResolverInterceptorSpec(model)),
107-
new PoetGeneratorTask(endpointRulesInternalDir(), model.getFileHeader(), new RequestEndpointInterceptorSpec(model)));
105+
new PoetGeneratorTask(endpointRulesInternalDir(), model.getFileHeader(), new EndpointResolverUtilsSpec(model)));
108106
}
109107

110108
private GeneratorTask generateClientTests() {

codegen/src/main/java/software/amazon/awssdk/codegen/poet/auth/scheme/AuthSchemeInterceptorSpec.java

Lines changed: 0 additions & 524 deletions
This file was deleted.

codegen/src/main/java/software/amazon/awssdk/codegen/poet/builder/BaseClientBuilderClass.java

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -370,9 +370,6 @@ private MethodSpec finalizeServiceConfigurationMethod() {
370370

371371
List<ClassName> builtInInterceptors = new ArrayList<>();
372372

373-
builtInInterceptors.add(endpointRulesSpecUtils.resolverInterceptorName());
374-
builtInInterceptors.add(endpointRulesSpecUtils.requestModifierInterceptorName());
375-
376373
for (String interceptor : model.getCustomizationConfig().getInterceptors()) {
377374
builtInInterceptors.add(ClassName.bestGuess(interceptor));
378375
}

codegen/src/main/java/software/amazon/awssdk/codegen/poet/client/AsyncClientClass.java

Lines changed: 91 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -44,7 +44,9 @@
4444
import java.util.Collections;
4545
import java.util.Comparator;
4646
import java.util.List;
47+
import java.util.Optional;
4748
import java.util.concurrent.CompletableFuture;
49+
import java.util.concurrent.CompletionException;
4850
import java.util.concurrent.Executor;
4951
import java.util.concurrent.ScheduledExecutorService;
5052
import java.util.stream.Collectors;
@@ -76,6 +78,8 @@
7678
import software.amazon.awssdk.codegen.poet.model.ServiceClientConfigurationUtils;
7779
import software.amazon.awssdk.codegen.poet.rules.EndpointRulesSpecUtils;
7880
import software.amazon.awssdk.core.RequestOverrideConfiguration;
81+
import software.amazon.awssdk.core.SdkRequest;
82+
import software.amazon.awssdk.core.SelectedAuthScheme;
7983
import software.amazon.awssdk.core.async.AsyncResponseTransformer;
8084
import software.amazon.awssdk.core.async.AsyncResponseTransformerUtils;
8185
import software.amazon.awssdk.core.async.SdkPublisher;
@@ -85,7 +89,11 @@
8589
import software.amazon.awssdk.core.client.handler.AsyncClientHandler;
8690
import software.amazon.awssdk.core.endpointdiscovery.EndpointDiscoveryRefreshCache;
8791
import software.amazon.awssdk.core.endpointdiscovery.EndpointDiscoveryRequest;
92+
import software.amazon.awssdk.core.exception.SdkClientException;
93+
import software.amazon.awssdk.core.interceptor.ExecutionAttributes;
94+
import software.amazon.awssdk.core.interceptor.SdkInternalExecutionAttribute;
8895
import software.amazon.awssdk.core.metrics.CoreMetric;
96+
import software.amazon.awssdk.endpoints.Endpoint;
8997
import software.amazon.awssdk.identity.spi.AwsCredentialsIdentity;
9098
import software.amazon.awssdk.metrics.MetricCollector;
9199
import software.amazon.awssdk.metrics.MetricPublisher;
@@ -172,7 +180,8 @@ protected void addAdditionalMethods(TypeSpec.Builder type) {
172180
.addMethods(protocolSpec.additionalMethods())
173181
.addMethod(protocolSpec.initProtocolFactory(model))
174182
.addMethod(resolveMetricPublishersMethod())
175-
.addMethod(ClientClassUtils.resolveAuthSchemeOptionsMethod(authSchemeSpecUtils, endpointRulesSpecUtils));
183+
.addMethod(ClientClassUtils.resolveAuthSchemeOptionsMethod(authSchemeSpecUtils, endpointRulesSpecUtils))
184+
.addMethod(resolveEndpointMethod());
176185

177186
type.addMethod(ClientClassUtils.updateRetryStrategyClientConfigurationMethod());
178187
type.addMethod(updateSdkClientConfigurationMethod(configurationUtils.serviceClientConfigurationBuilderClassName(),
@@ -581,6 +590,87 @@ private MethodSpec resolveMetricPublishersMethod() {
581590
return methodBuilder.build();
582591
}
583592

593+
private MethodSpec resolveEndpointMethod() {
594+
ClassName utilsClass = endpointRulesSpecUtils.endpointResolverUtilsName();
595+
ClassName endpointParamsClass = endpointRulesSpecUtils.parametersClassName();
596+
ClassName providerInterface = endpointRulesSpecUtils.providerInterfaceName();
597+
ClassName awsEndpointProviderUtils = endpointRulesSpecUtils.sharedAwsEndpointProviderUtilsName();
598+
ClassName awsEndpointAttribute = ClassName.get("software.amazon.awssdk.awscore.endpoints", "AwsEndpointAttribute");
599+
ClassName endpointAuthScheme = ClassName.get("software.amazon.awssdk.awscore.endpoints.authscheme", "EndpointAuthScheme");
600+
601+
MethodSpec.Builder b = MethodSpec.methodBuilder("resolveEndpoint")
602+
.addModifiers(PRIVATE)
603+
.returns(Endpoint.class)
604+
.addParameter(SdkRequest.class, "request")
605+
.addParameter(ExecutionAttributes.class, "executionAttributes")
606+
.addParameter(String.class, "operationName");
607+
608+
b.addStatement("$1T provider = ($1T) executionAttributes.getAttribute($2T.ENDPOINT_PROVIDER)",
609+
providerInterface, SdkInternalExecutionAttribute.class);
610+
611+
b.beginControlFlow("try");
612+
b.addStatement("$T endpointParams = $T.ruleParams(request, executionAttributes)",
613+
endpointParamsClass, utilsClass);
614+
b.addStatement("$T endpoint = provider.resolveEndpoint(endpointParams).join()", Endpoint.class);
615+
616+
b.beginControlFlow("if (!$T.disableHostPrefixInjection(executionAttributes))", awsEndpointProviderUtils);
617+
b.addStatement("$T hostPrefix = $T.hostPrefix(operationName, request)",
618+
ParameterizedTypeName.get(Optional.class, String.class), utilsClass);
619+
b.beginControlFlow("if (hostPrefix.isPresent())");
620+
b.addStatement("endpoint = $T.addHostPrefix(endpoint, hostPrefix.get())", awsEndpointProviderUtils);
621+
b.endControlFlow();
622+
b.endControlFlow();
623+
624+
b.addStatement("$T endpointAuthSchemes = endpoint.attribute($T.AUTH_SCHEMES)",
625+
ParameterizedTypeName.get(ClassName.get(List.class), endpointAuthScheme),
626+
awsEndpointAttribute);
627+
b.addStatement("$T selectedAuthScheme = executionAttributes.getAttribute($T.SELECTED_AUTH_SCHEME)",
628+
ParameterizedTypeName.get(ClassName.get(SelectedAuthScheme.class),
629+
WildcardTypeName.subtypeOf(Object.class)),
630+
SdkInternalExecutionAttribute.class);
631+
b.beginControlFlow("if (endpointAuthSchemes != null && selectedAuthScheme != null)");
632+
b.addStatement("selectedAuthScheme = $T.authSchemeWithEndpointSignerProperties(endpointAuthSchemes, selectedAuthScheme)",
633+
utilsClass);
634+
635+
if (authSchemeSpecUtils.usesSigV4a() || authSchemeSpecUtils.generateEndpointBasedParams()) {
636+
ClassName awsV4aAuthScheme = ClassName.get("software.amazon.awssdk.http.auth.aws.scheme", "AwsV4aAuthScheme");
637+
ClassName awsV4aHttpSigner = ClassName.get("software.amazon.awssdk.http.auth.aws.signer", "AwsV4aHttpSigner");
638+
ClassName regionSet = ClassName.get("software.amazon.awssdk.http.auth.aws.signer", "RegionSet");
639+
ClassName authSchemeOption = ClassName.get("software.amazon.awssdk.http.auth.spi.scheme", "AuthSchemeOption");
640+
641+
b.addComment("Precedence of SigV4a RegionSet is set according to multi-auth SigV4a specifications");
642+
b.beginControlFlow("if (selectedAuthScheme.authSchemeOption().schemeId().equals($T.SCHEME_ID) "
643+
+ "&& selectedAuthScheme.authSchemeOption().signerProperty($T.REGION_SET) == null)",
644+
awsV4aAuthScheme, awsV4aHttpSigner);
645+
b.addStatement("$T optionBuilder = selectedAuthScheme.authSchemeOption().toBuilder()",
646+
authSchemeOption.nestedClass("Builder"));
647+
b.addStatement("$1T rs = $1T.create(endpointParams.region().id())", regionSet);
648+
b.addStatement("optionBuilder.putSignerProperty($T.REGION_SET, rs)", awsV4aHttpSigner);
649+
b.addStatement("selectedAuthScheme = new $T(selectedAuthScheme.identity(), selectedAuthScheme.signer(), "
650+
+ "optionBuilder.build())", SelectedAuthScheme.class);
651+
b.endControlFlow();
652+
}
653+
654+
b.addStatement("executionAttributes.putAttribute($T.SELECTED_AUTH_SCHEME, selectedAuthScheme)",
655+
SdkInternalExecutionAttribute.class);
656+
b.endControlFlow();
657+
658+
b.addStatement("$T.setMetricValues(endpoint, executionAttributes)", utilsClass);
659+
660+
b.addStatement("return endpoint");
661+
662+
b.nextControlFlow("catch ($T e)", CompletionException.class);
663+
b.addStatement("$T cause = e.getCause()", Throwable.class);
664+
b.beginControlFlow("if (cause instanceof $T)", SdkClientException.class);
665+
b.addStatement("throw ($T) cause", SdkClientException.class);
666+
b.endControlFlow();
667+
b.addStatement("throw $T.create($S + cause.getMessage(), cause)",
668+
SdkClientException.class, "Endpoint resolution failed: ");
669+
b.endControlFlow();
670+
671+
return b.build();
672+
}
673+
584674
private void addScheduledExecutorIfNeeded(Builder classBuilder) {
585675
if (!hasScheduledExecutor) {
586676
classBuilder.addField(FieldSpec.builder(ClassName.get(ScheduledExecutorService.class), "executorService")

codegen/src/main/java/software/amazon/awssdk/codegen/poet/client/ClientClassUtils.java

Lines changed: 11 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -406,9 +406,6 @@ private static void addSimpleAuthSchemeResolution(MethodSpec.Builder builder,
406406
ClassName.get(Set.class), awsClientOption);
407407
builder.beginControlFlow("if (!$T.isNullOrEmpty(sigv4aRegionSet))", CollectionUtils.class);
408408
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);
412409
builder.endControlFlow();
413410
}
414411

@@ -422,7 +419,7 @@ private static void addEndpointBasedAuthSchemeResolution(MethodSpec.Builder buil
422419
ClassName paramsInterface = authSchemeSpecUtils.parametersInterfaceName();
423420
ClassName awsClientOption = ClassName.get("software.amazon.awssdk.awscore.client.config", "AwsClientOption");
424421
ClassName endpointParamsClass = endpointRulesSpecUtils.parametersClassName();
425-
ClassName resolverInterceptor = endpointRulesSpecUtils.resolverInterceptorName();
422+
ClassName endpointResolverUtils = endpointRulesSpecUtils.endpointResolverUtilsName();
426423
ClassName executionAttributesClass = ClassName.get("software.amazon.awssdk.core.interceptor", "ExecutionAttributes");
427424
ClassName awsExecutionAttribute = ClassName.get("software.amazon.awssdk.awscore", "AwsExecutionAttribute");
428425
ClassName sdkExecutionAttribute = ClassName.get("software.amazon.awssdk.core.interceptor", "SdkExecutionAttribute");
@@ -447,7 +444,7 @@ private static void addEndpointBasedAuthSchemeResolution(MethodSpec.Builder buil
447444
sdkInternalExecutionAttribute, SdkClientOption.class);
448445

449446
builder.addStatement("$T endpointParams = $T.ruleParams(request, executionAttributes)",
450-
endpointParamsClass, resolverInterceptor);
447+
endpointParamsClass, endpointResolverUtils);
451448

452449
builder.addStatement("$T.Builder paramsBuilder = $T.builder()", paramsInterface, paramsInterface);
453450

@@ -467,6 +464,15 @@ private static void addEndpointBasedAuthSchemeResolution(MethodSpec.Builder buil
467464
builder.addStatement("paramsBuilder.region(clientConfiguration.option($T.AWS_REGION))", awsClientOption);
468465
}
469466

467+
if (authSchemeSpecUtils.hasSigV4aSupport()) {
468+
ClassName regionSet = ClassName.get("software.amazon.awssdk.http.auth.aws.signer", "RegionSet");
469+
builder.addStatement("$T<String> sigv4aRegionSet = clientConfiguration.option($T.AWS_SIGV4A_SIGNING_REGION_SET)",
470+
ClassName.get(Set.class), awsClientOption);
471+
builder.beginControlFlow("if (!$T.isNullOrEmpty(sigv4aRegionSet))", CollectionUtils.class);
472+
builder.addStatement("paramsBuilder.regionSet($T.create(sigv4aRegionSet))", regionSet);
473+
builder.endControlFlow();
474+
}
475+
470476
ClassName paramsBuilderClass = authSchemeSpecUtils.parametersEndpointAwareDefaultImplName().nestedClass("Builder");
471477
ClassName endpointProviderInterface = endpointRulesSpecUtils.providerInterfaceName();
472478

0 commit comments

Comments
 (0)