Skip to content

Commit 79cb513

Browse files
authored
Splitting endpoint resolution and modifying the request URI into two separate interceptors (#3450)
1 parent cc97689 commit 79cb513

File tree

14 files changed

+300
-38
lines changed

14 files changed

+300
-38
lines changed

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

Lines changed: 9 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,8 @@
1616
package software.amazon.awssdk.codegen.emitters.tasks;
1717

1818
import java.util.ArrayList;
19+
import java.util.Arrays;
20+
import java.util.Collection;
1921
import java.util.List;
2022
import java.util.Map;
2123
import software.amazon.awssdk.codegen.emitters.GeneratorTask;
@@ -25,11 +27,12 @@
2527
import software.amazon.awssdk.codegen.model.service.ClientContextParam;
2628
import software.amazon.awssdk.codegen.poet.rules.ClientContextParamsClassSpec;
2729
import software.amazon.awssdk.codegen.poet.rules.EndpointParametersClassSpec;
28-
import software.amazon.awssdk.codegen.poet.rules.EndpointProviderInterceptorSpec;
2930
import software.amazon.awssdk.codegen.poet.rules.EndpointProviderInterfaceSpec;
3031
import software.amazon.awssdk.codegen.poet.rules.EndpointProviderSpec;
3132
import software.amazon.awssdk.codegen.poet.rules.EndpointProviderTestSpec;
33+
import software.amazon.awssdk.codegen.poet.rules.EndpointResolverInterceptorSpec;
3234
import software.amazon.awssdk.codegen.poet.rules.EndpointRulesClientTestSpec;
35+
import software.amazon.awssdk.codegen.poet.rules.RequestEndpointInterceptorSpec;
3336

3437
public final class EndpointProviderTasks extends BaseGeneratorTasks {
3538
private final GeneratorTaskParams generatorTaskParams;
@@ -45,7 +48,7 @@ protected List<GeneratorTask> createTasks() throws Exception {
4548
tasks.add(generateInterface());
4649
tasks.add(generateParams());
4750
tasks.add(generateDefaultProvider());
48-
tasks.add(generateInterceptor());
51+
tasks.addAll(generateInterceptors());
4952
if (shouldGenerateTests()) {
5053
tasks.add(generateClientTests());
5154
tasks.add(generateProviderTests());
@@ -69,9 +72,10 @@ private GeneratorTask generateDefaultProvider() {
6972
return new PoetGeneratorTask(endpointRulesInternalDir(), model.getFileHeader(), new EndpointProviderSpec(model));
7073
}
7174

72-
private GeneratorTask generateInterceptor() {
73-
return new PoetGeneratorTask(endpointRulesInternalDir(), model.getFileHeader(),
74-
new EndpointProviderInterceptorSpec(model));
75+
private Collection<GeneratorTask> generateInterceptors() {
76+
return Arrays.asList(
77+
new PoetGeneratorTask(endpointRulesInternalDir(), model.getFileHeader(), new EndpointResolverInterceptorSpec(model)),
78+
new PoetGeneratorTask(endpointRulesInternalDir(), model.getFileHeader(), new RequestEndpointInterceptorSpec(model)));
7579
}
7680

7781
private GeneratorTask generateClientTests() {

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

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -239,7 +239,8 @@ private MethodSpec finalizeServiceConfigurationMethod() {
239239
ExecutionInterceptor.class),
240240
ArrayList.class);
241241

242-
builder.addStatement("additionalInterceptors.add(new $T())", endpointRulesSpecUtils.interceptorName());
242+
builder.addStatement("additionalInterceptors.add(new $T())", endpointRulesSpecUtils.resolverInterceptorName());
243+
builder.addStatement("additionalInterceptors.add(new $T())", endpointRulesSpecUtils.requestModifierInterceptorName());
243244

244245
if (model.getMetadata().isQueryProtocol()) {
245246
builder.addStatement("additionalInterceptors.add(new $T())", QueryParametersToBodyInterceptor.class);
Lines changed: 13 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -42,15 +42,14 @@
4242
import software.amazon.awssdk.core.interceptor.ExecutionInterceptor;
4343
import software.amazon.awssdk.core.interceptor.SdkInternalExecutionAttribute;
4444
import software.amazon.awssdk.core.rules.model.Endpoint;
45-
import software.amazon.awssdk.http.SdkHttpRequest;
4645
import software.amazon.awssdk.utils.AttributeMap;
4746

48-
public class EndpointProviderInterceptorSpec implements ClassSpec {
47+
public class EndpointResolverInterceptorSpec implements ClassSpec {
4948
private final IntermediateModel model;
5049
private final EndpointRulesSpecUtils endpointRulesSpecUtils;
5150
private final PoetExtension poetExtension;
5251

53-
public EndpointProviderInterceptorSpec(IntermediateModel model) {
52+
public EndpointResolverInterceptorSpec(IntermediateModel model) {
5453
this.model = model;
5554
this.endpointRulesSpecUtils = new EndpointRulesSpecUtils(model);
5655
this.poetExtension = new PoetExtension(model);
@@ -63,7 +62,7 @@ public TypeSpec poetSpec() {
6362
.addAnnotation(SdkInternalApi.class)
6463
.addSuperinterface(ExecutionInterceptor.class);
6564

66-
b.addMethod(modifyHttpRequestMethod());
65+
b.addMethod(modifyRequestMethod());
6766
b.addMethod(ruleParams());
6867

6968
b.addMethod(setContextParams());
@@ -81,38 +80,39 @@ public TypeSpec poetSpec() {
8180

8281
@Override
8382
public ClassName className() {
84-
return endpointRulesSpecUtils.interceptorName();
83+
return endpointRulesSpecUtils.resolverInterceptorName();
8584
}
8685

87-
private MethodSpec modifyHttpRequestMethod() {
86+
private MethodSpec modifyRequestMethod() {
8887

89-
MethodSpec.Builder b = MethodSpec.methodBuilder("modifyHttpRequest")
88+
MethodSpec.Builder b = MethodSpec.methodBuilder("modifyRequest")
9089
.addModifiers(Modifier.PUBLIC)
9190
.addAnnotation(Override.class)
92-
.returns(SdkHttpRequest.class)
93-
.addParameter(Context.ModifyHttpRequest.class, "context")
91+
.returns(SdkRequest.class)
92+
.addParameter(Context.ModifyRequest.class, "context")
9493
.addParameter(ExecutionAttributes.class, "executionAttributes");
9594

9695
String providerVar = "provider";
9796

9897
// We skip resolution if the source of the endpoint is the endpoint discovery call
9998
b.beginControlFlow("if ($1T.endpointIsDiscovered(executionAttributes))",
10099
AwsProviderUtils.class)
101-
.addStatement("return context.httpRequest()")
102-
.endControlFlow();
100+
.addStatement("return context.request()")
101+
.endControlFlow().build();
103102

104103
b.addStatement("$1T $2N = ($1T) executionAttributes.getAttribute($3T.ENDPOINT_PROVIDER)",
105104
endpointRulesSpecUtils.providerInterfaceName(), providerVar, SdkInternalExecutionAttribute.class);
106105
b.addStatement("$T result = $N.resolveEndpoint(ruleParams(context, executionAttributes))", Endpoint.class, providerVar);
107-
b.addStatement("return $T.setUri(context.httpRequest(), result.url())", AwsProviderUtils.class);
106+
b.addStatement("executionAttributes.putAttribute(SdkInternalExecutionAttribute.RESOLVED_ENDPOINT, result)");
107+
b.addStatement("return context.request()");
108108
return b.build();
109109
}
110110

111111
private MethodSpec ruleParams() {
112112
MethodSpec.Builder b = MethodSpec.methodBuilder("ruleParams")
113113
.addModifiers(Modifier.PRIVATE, Modifier.STATIC)
114114
.returns(endpointRulesSpecUtils.parametersClassName())
115-
.addParameter(Context.ModifyHttpRequest.class, "context")
115+
.addParameter(Context.ModifyRequest.class, "context")
116116
.addParameter(ExecutionAttributes.class, "executionAttributes");
117117

118118
b.addStatement("$T builder = $T.builder()", paramsBuilderClass(), endpointRulesSpecUtils.parametersClassName());

codegen/src/main/java/software/amazon/awssdk/codegen/poet/rules/EndpointRulesSpecUtils.java

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -56,10 +56,16 @@ public ClassName providerDefaultImplName() {
5656
"Default" + providerInterfaceName().simpleName());
5757
}
5858

59-
public ClassName interceptorName() {
59+
public ClassName resolverInterceptorName() {
6060
Metadata md = intermediateModel.getMetadata();
6161
return ClassName.get(md.getFullInternalEndpointRulesPackageName(),
62-
md.getServiceName() + "EndpointInterceptor");
62+
md.getServiceName() + "ResolveEndpointInterceptor");
63+
}
64+
65+
public ClassName requestModifierInterceptorName() {
66+
Metadata md = intermediateModel.getMetadata();
67+
return ClassName.get(md.getFullInternalEndpointRulesPackageName(),
68+
md.getServiceName() + "RequestSetEndpointInterceptor");
6369
}
6470

6571
public ClassName clientEndpointTestsName() {
Lines changed: 81 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,81 @@
1+
/*
2+
* Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
3+
*
4+
* Licensed under the Apache License, Version 2.0 (the "License").
5+
* You may not use this file except in compliance with the License.
6+
* A copy of the License is located at
7+
*
8+
* http://aws.amazon.com/apache2.0
9+
*
10+
* or in the "license" file accompanying this file. This file is distributed
11+
* on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either
12+
* express or implied. See the License for the specific language governing
13+
* permissions and limitations under the License.
14+
*/
15+
16+
package software.amazon.awssdk.codegen.poet.rules;
17+
18+
import com.squareup.javapoet.ClassName;
19+
import com.squareup.javapoet.MethodSpec;
20+
import com.squareup.javapoet.TypeSpec;
21+
import javax.lang.model.element.Modifier;
22+
import software.amazon.awssdk.annotations.SdkInternalApi;
23+
import software.amazon.awssdk.awscore.rules.AwsProviderUtils;
24+
import software.amazon.awssdk.codegen.model.intermediate.IntermediateModel;
25+
import software.amazon.awssdk.codegen.poet.ClassSpec;
26+
import software.amazon.awssdk.codegen.poet.PoetUtils;
27+
import software.amazon.awssdk.core.interceptor.Context;
28+
import software.amazon.awssdk.core.interceptor.ExecutionAttributes;
29+
import software.amazon.awssdk.core.interceptor.ExecutionInterceptor;
30+
import software.amazon.awssdk.core.interceptor.SdkInternalExecutionAttribute;
31+
import software.amazon.awssdk.core.rules.model.Endpoint;
32+
import software.amazon.awssdk.http.SdkHttpRequest;
33+
34+
public class RequestEndpointInterceptorSpec implements ClassSpec {
35+
private final EndpointRulesSpecUtils endpointRulesSpecUtils;
36+
37+
public RequestEndpointInterceptorSpec(IntermediateModel model) {
38+
this.endpointRulesSpecUtils = new EndpointRulesSpecUtils(model);
39+
}
40+
41+
@Override
42+
public TypeSpec poetSpec() {
43+
TypeSpec.Builder b = PoetUtils.createClassBuilder(className())
44+
.addModifiers(Modifier.PUBLIC, Modifier.FINAL)
45+
.addAnnotation(SdkInternalApi.class)
46+
.addSuperinterface(ExecutionInterceptor.class);
47+
48+
b.addMethod(modifyHttpRequestMethod());
49+
50+
return b.build();
51+
}
52+
53+
@Override
54+
public ClassName className() {
55+
return endpointRulesSpecUtils.requestModifierInterceptorName();
56+
}
57+
58+
private MethodSpec modifyHttpRequestMethod() {
59+
60+
MethodSpec.Builder b = MethodSpec.methodBuilder("modifyHttpRequest")
61+
.addModifiers(Modifier.PUBLIC)
62+
.addAnnotation(Override.class)
63+
.returns(SdkHttpRequest.class)
64+
.addParameter(Context.ModifyHttpRequest.class, "context")
65+
.addParameter(ExecutionAttributes.class, "executionAttributes");
66+
67+
68+
// We skip setting the endpoint here if the source of the endpoint is the endpoint discovery call
69+
b.beginControlFlow("if ($1T.endpointIsDiscovered(executionAttributes))",
70+
AwsProviderUtils.class)
71+
.addStatement("return context.httpRequest()")
72+
.endControlFlow().build();
73+
74+
b.addStatement("$1T endpoint = ($1T) executionAttributes.getAttribute($2T.RESOLVED_ENDPOINT)",
75+
Endpoint.class,
76+
SdkInternalExecutionAttribute.class);
77+
b.addStatement("return $T.setUri(context.httpRequest(), endpoint.url())", AwsProviderUtils.class);
78+
return b.build();
79+
}
80+
81+
}
Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -22,10 +22,10 @@
2222
import software.amazon.awssdk.codegen.poet.ClassSpec;
2323
import software.amazon.awssdk.codegen.poet.ClientTestModels;
2424

25-
public class EndpointProviderInterceptorSpecTest {
25+
public class EndpointResolverInterceptorSpecTest {
2626
@Test
27-
public void endpointProviderInterceptorClass() {
28-
ClassSpec endpointProviderInterceptor = new EndpointProviderInterceptorSpec(ClientTestModels.queryServiceModels());
29-
assertThat(endpointProviderInterceptor, generatesTo("endpoint-provider-interceptor.java"));
27+
public void endpointResolverInterceptorClass() {
28+
ClassSpec endpointProviderInterceptor = new EndpointResolverInterceptorSpec(ClientTestModels.queryServiceModels());
29+
assertThat(endpointProviderInterceptor, generatesTo("endpoint-resolve-interceptor.java"));
3030
}
3131
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
/*
2+
* Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
3+
*
4+
* Licensed under the Apache License, Version 2.0 (the "License").
5+
* You may not use this file except in compliance with the License.
6+
* A copy of the License is located at
7+
*
8+
* http://aws.amazon.com/apache2.0
9+
*
10+
* or in the "license" file accompanying this file. This file is distributed
11+
* on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either
12+
* express or implied. See the License for the specific language governing
13+
* permissions and limitations under the License.
14+
*/
15+
16+
package software.amazon.awssdk.codegen.poet.rules;
17+
18+
import static org.hamcrest.MatcherAssert.assertThat;
19+
import static software.amazon.awssdk.codegen.poet.PoetMatchers.generatesTo;
20+
21+
import org.junit.jupiter.api.Test;
22+
import software.amazon.awssdk.codegen.poet.ClassSpec;
23+
import software.amazon.awssdk.codegen.poet.ClientTestModels;
24+
25+
public class RequestEndpointProviderInterceptorSpecTest {
26+
@Test
27+
public void requestSetEndpointInterceptorClass() {
28+
ClassSpec endpointProviderInterceptor = new RequestEndpointInterceptorSpec(ClientTestModels.queryServiceModels());
29+
assertThat(endpointProviderInterceptor, generatesTo("request-set-endpoint-interceptor.java"));
30+
}
31+
}

codegen/src/test/resources/software/amazon/awssdk/codegen/poet/builder/test-client-builder-class.java

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,8 @@
1616
import software.amazon.awssdk.core.interceptor.ExecutionInterceptor;
1717
import software.amazon.awssdk.core.signer.Signer;
1818
import software.amazon.awssdk.services.json.rules.JsonEndpointProvider;
19-
import software.amazon.awssdk.services.json.rules.internal.JsonEndpointInterceptor;
19+
import software.amazon.awssdk.services.json.rules.internal.JsonRequestSetEndpointInterceptor;
20+
import software.amazon.awssdk.services.json.rules.internal.JsonResolveEndpointInterceptor;
2021
import software.amazon.awssdk.utils.AttributeMap;
2122
import software.amazon.awssdk.utils.CollectionUtils;
2223
import software.amazon.awssdk.utils.Validate;
@@ -51,7 +52,8 @@ protected final SdkClientConfiguration finalizeServiceConfiguration(SdkClientCon
5152
List<ExecutionInterceptor> interceptors = interceptorFactory
5253
.getInterceptors("software/amazon/awssdk/services/json/execution.interceptors");
5354
List<ExecutionInterceptor> additionalInterceptors = new ArrayList<>();
54-
additionalInterceptors.add(new JsonEndpointInterceptor());
55+
additionalInterceptors.add(new JsonResolveEndpointInterceptor());
56+
additionalInterceptors.add(new JsonRequestSetEndpointInterceptor());
5557
interceptors = CollectionUtils.mergeLists(interceptors, additionalInterceptors);
5658
interceptors = CollectionUtils.mergeLists(interceptors, config.option(SdkClientOption.EXECUTION_INTERCEPTORS));
5759
ServiceConfiguration.Builder c = ((ServiceConfiguration) config.option(SdkClientOption.SERVICE_CONFIGURATION))

codegen/src/test/resources/software/amazon/awssdk/codegen/poet/builder/test-client-builder-internal-defaults-class.java

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,8 @@
1414
import software.amazon.awssdk.core.retry.RetryMode;
1515
import software.amazon.awssdk.core.signer.Signer;
1616
import software.amazon.awssdk.services.json.rules.JsonEndpointProvider;
17-
import software.amazon.awssdk.services.json.rules.internal.JsonEndpointInterceptor;
17+
import software.amazon.awssdk.services.json.rules.internal.JsonRequestSetEndpointInterceptor;
18+
import software.amazon.awssdk.services.json.rules.internal.JsonResolveEndpointInterceptor;
1819
import software.amazon.awssdk.utils.CollectionUtils;
1920

2021
/**
@@ -54,7 +55,8 @@ protected final SdkClientConfiguration finalizeServiceConfiguration(SdkClientCon
5455
List<ExecutionInterceptor> interceptors = interceptorFactory
5556
.getInterceptors("software/amazon/awssdk/services/json/execution.interceptors");
5657
List<ExecutionInterceptor> additionalInterceptors = new ArrayList<>();
57-
additionalInterceptors.add(new JsonEndpointInterceptor());
58+
additionalInterceptors.add(new JsonResolveEndpointInterceptor());
59+
additionalInterceptors.add(new JsonRequestSetEndpointInterceptor());
5860
interceptors = CollectionUtils.mergeLists(interceptors, additionalInterceptors);
5961
interceptors = CollectionUtils.mergeLists(interceptors, config.option(SdkClientOption.EXECUTION_INTERCEPTORS));
6062
return config.toBuilder().option(SdkClientOption.EXECUTION_INTERCEPTORS, interceptors).build();

codegen/src/test/resources/software/amazon/awssdk/codegen/poet/builder/test-query-client-builder-class.java

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,8 @@
1515
import software.amazon.awssdk.protocols.query.interceptor.QueryParametersToBodyInterceptor;
1616
import software.amazon.awssdk.services.query.rules.QueryClientContextParams;
1717
import software.amazon.awssdk.services.query.rules.QueryEndpointProvider;
18-
import software.amazon.awssdk.services.query.rules.internal.QueryEndpointInterceptor;
18+
import software.amazon.awssdk.services.query.rules.internal.QueryRequestSetEndpointInterceptor;
19+
import software.amazon.awssdk.services.query.rules.internal.QueryResolveEndpointInterceptor;
1920
import software.amazon.awssdk.utils.CollectionUtils;
2021

2122
/**
@@ -47,7 +48,8 @@ protected final SdkClientConfiguration finalizeServiceConfiguration(SdkClientCon
4748
List<ExecutionInterceptor> interceptors = interceptorFactory
4849
.getInterceptors("software/amazon/awssdk/services/query/execution.interceptors");
4950
List<ExecutionInterceptor> additionalInterceptors = new ArrayList<>();
50-
additionalInterceptors.add(new QueryEndpointInterceptor());
51+
additionalInterceptors.add(new QueryResolveEndpointInterceptor());
52+
additionalInterceptors.add(new QueryRequestSetEndpointInterceptor());
5153
additionalInterceptors.add(new QueryParametersToBodyInterceptor());
5254
interceptors = CollectionUtils.mergeLists(interceptors, additionalInterceptors);
5355
interceptors = CollectionUtils.mergeLists(interceptors, config.option(SdkClientOption.EXECUTION_INTERCEPTORS));

0 commit comments

Comments
 (0)