|
44 | 44 | import java.util.Collections; |
45 | 45 | import java.util.Comparator; |
46 | 46 | import java.util.List; |
| 47 | +import java.util.Optional; |
47 | 48 | import java.util.concurrent.CompletableFuture; |
| 49 | +import java.util.concurrent.CompletionException; |
48 | 50 | import java.util.concurrent.Executor; |
49 | 51 | import java.util.concurrent.ScheduledExecutorService; |
50 | 52 | import java.util.stream.Collectors; |
|
76 | 78 | import software.amazon.awssdk.codegen.poet.model.ServiceClientConfigurationUtils; |
77 | 79 | import software.amazon.awssdk.codegen.poet.rules.EndpointRulesSpecUtils; |
78 | 80 | import software.amazon.awssdk.core.RequestOverrideConfiguration; |
| 81 | +import software.amazon.awssdk.core.SdkRequest; |
| 82 | +import software.amazon.awssdk.core.SelectedAuthScheme; |
79 | 83 | import software.amazon.awssdk.core.async.AsyncResponseTransformer; |
80 | 84 | import software.amazon.awssdk.core.async.AsyncResponseTransformerUtils; |
81 | 85 | import software.amazon.awssdk.core.async.SdkPublisher; |
|
85 | 89 | import software.amazon.awssdk.core.client.handler.AsyncClientHandler; |
86 | 90 | import software.amazon.awssdk.core.endpointdiscovery.EndpointDiscoveryRefreshCache; |
87 | 91 | 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; |
88 | 95 | import software.amazon.awssdk.core.metrics.CoreMetric; |
| 96 | +import software.amazon.awssdk.endpoints.Endpoint; |
89 | 97 | import software.amazon.awssdk.identity.spi.AwsCredentialsIdentity; |
90 | 98 | import software.amazon.awssdk.metrics.MetricCollector; |
91 | 99 | import software.amazon.awssdk.metrics.MetricPublisher; |
@@ -172,7 +180,8 @@ protected void addAdditionalMethods(TypeSpec.Builder type) { |
172 | 180 | .addMethods(protocolSpec.additionalMethods()) |
173 | 181 | .addMethod(protocolSpec.initProtocolFactory(model)) |
174 | 182 | .addMethod(resolveMetricPublishersMethod()) |
175 | | - .addMethod(ClientClassUtils.resolveAuthSchemeOptionsMethod(authSchemeSpecUtils, endpointRulesSpecUtils)); |
| 183 | + .addMethod(ClientClassUtils.resolveAuthSchemeOptionsMethod(authSchemeSpecUtils, endpointRulesSpecUtils)) |
| 184 | + .addMethod(resolveEndpointMethod()); |
176 | 185 |
|
177 | 186 | type.addMethod(ClientClassUtils.updateRetryStrategyClientConfigurationMethod()); |
178 | 187 | type.addMethod(updateSdkClientConfigurationMethod(configurationUtils.serviceClientConfigurationBuilderClassName(), |
@@ -581,6 +590,87 @@ private MethodSpec resolveMetricPublishersMethod() { |
581 | 590 | return methodBuilder.build(); |
582 | 591 | } |
583 | 592 |
|
| 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 | + |
584 | 674 | private void addScheduledExecutorIfNeeded(Builder classBuilder) { |
585 | 675 | if (!hasScheduledExecutor) { |
586 | 676 | classBuilder.addField(FieldSpec.builder(ClassName.get(ScheduledExecutorService.class), "executorService") |
|
0 commit comments