Skip to content

Commit c7c731f

Browse files
authored
Move QueryParametersToBodyInterceptor to front of interceptor chain (#4109)
* Move QueryParametersToBodyInterceptor to front of interceptor chain * Move customization.config interceptors to front of interceptor chain - for query protocols * Refactoring * Add codegen tests * Refactoring * Refactoring
1 parent ce8e53b commit c7c731f

File tree

10 files changed

+261
-162
lines changed

10 files changed

+261
-162
lines changed

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

Lines changed: 54 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -18,8 +18,12 @@
1818
import com.squareup.javapoet.ClassName;
1919
import com.squareup.javapoet.MethodSpec;
2020
import com.squareup.javapoet.ParameterizedTypeName;
21+
import com.squareup.javapoet.TypeName;
2122
import com.squareup.javapoet.TypeSpec;
2223
import java.net.URI;
24+
import java.util.ArrayList;
25+
import java.util.Collections;
26+
import java.util.List;
2327
import javax.lang.model.element.Modifier;
2428
import software.amazon.awssdk.annotations.SdkInternalApi;
2529
import software.amazon.awssdk.auth.token.credentials.SdkTokenProvider;
@@ -32,6 +36,9 @@
3236
import software.amazon.awssdk.codegen.utils.AuthUtils;
3337
import software.amazon.awssdk.core.client.config.SdkClientConfiguration;
3438
import software.amazon.awssdk.core.client.config.SdkClientOption;
39+
import software.amazon.awssdk.core.interceptor.ExecutionInterceptor;
40+
import software.amazon.awssdk.protocols.query.interceptor.QueryParametersToBodyInterceptor;
41+
import software.amazon.awssdk.utils.CollectionUtils;
3542

3643
public class AsyncClientBuilderClass implements ClassSpec {
3744
private final IntermediateModel model;
@@ -119,26 +126,53 @@ private MethodSpec endpointProviderMethod() {
119126
}
120127

121128
private MethodSpec buildClientMethod() {
122-
return MethodSpec.methodBuilder("buildClient")
123-
.addAnnotation(Override.class)
124-
.addModifiers(Modifier.PROTECTED, Modifier.FINAL)
125-
.returns(clientInterfaceName)
126-
.addStatement("$T clientConfiguration = super.asyncClientConfiguration()", SdkClientConfiguration.class)
127-
.addStatement("this.validateClientOptions(clientConfiguration)")
128-
.addStatement("$T endpointOverride = null", URI.class)
129-
.addCode("if (clientConfiguration.option($T.ENDPOINT_OVERRIDDEN) != null"
130-
+ "&& $T.TRUE.equals(clientConfiguration.option($T.ENDPOINT_OVERRIDDEN))) {"
131-
+ "endpointOverride = clientConfiguration.option($T.ENDPOINT);"
132-
+ "}",
133-
SdkClientOption.class, Boolean.class, SdkClientOption.class, SdkClientOption.class)
134-
.addStatement("$T serviceClientConfiguration = $T.builder()"
135-
+ ".overrideConfiguration(overrideConfiguration())"
136-
+ ".region(clientConfiguration.option($T.AWS_REGION))"
137-
+ ".endpointOverride(endpointOverride)"
138-
+ ".build()",
139-
serviceConfigClassName, serviceConfigClassName, AwsClientOption.class)
140-
.addStatement("return new $T(serviceClientConfiguration, clientConfiguration)", clientClassName)
141-
.build();
129+
MethodSpec.Builder b = MethodSpec.methodBuilder("buildClient")
130+
.addAnnotation(Override.class)
131+
.addModifiers(Modifier.PROTECTED, Modifier.FINAL)
132+
.returns(clientInterfaceName)
133+
.addStatement("$T clientConfiguration = super.asyncClientConfiguration()",
134+
SdkClientConfiguration.class);
135+
136+
addQueryProtocolInterceptors(b);
137+
138+
return b.addStatement("this.validateClientOptions(clientConfiguration)")
139+
.addStatement("$T endpointOverride = null", URI.class)
140+
.addCode("if (clientConfiguration.option($T.ENDPOINT_OVERRIDDEN) != null"
141+
+ "&& $T.TRUE.equals(clientConfiguration.option($T.ENDPOINT_OVERRIDDEN))) {"
142+
+ "endpointOverride = clientConfiguration.option($T.ENDPOINT);"
143+
+ "}",
144+
SdkClientOption.class, Boolean.class, SdkClientOption.class, SdkClientOption.class)
145+
.addStatement("$T serviceClientConfiguration = $T.builder()"
146+
+ ".overrideConfiguration(overrideConfiguration())"
147+
+ ".region(clientConfiguration.option($T.AWS_REGION))"
148+
+ ".endpointOverride(endpointOverride)"
149+
+ ".build()",
150+
serviceConfigClassName, serviceConfigClassName, AwsClientOption.class)
151+
.addStatement("return new $T(serviceClientConfiguration, clientConfiguration)", clientClassName)
152+
.build();
153+
}
154+
155+
private MethodSpec.Builder addQueryProtocolInterceptors(MethodSpec.Builder b) {
156+
if (!model.getMetadata().isQueryProtocol()) {
157+
return b;
158+
}
159+
160+
TypeName listType = ParameterizedTypeName.get(List.class, ExecutionInterceptor.class);
161+
162+
b.addStatement("$T interceptors = clientConfiguration.option($T.EXECUTION_INTERCEPTORS)",
163+
listType, SdkClientOption.class)
164+
.addStatement("$T queryParamsToBodyInterceptor = $T.singletonList(new $T())",
165+
listType, Collections.class, QueryParametersToBodyInterceptor.class)
166+
.addStatement("$T customizationInterceptors = new $T<>()", listType, ArrayList.class);
167+
168+
List<String> customInterceptors = model.getCustomizationConfig().getInterceptors();
169+
customInterceptors.forEach(i -> b.addStatement("customizationInterceptors.add(new $T())", ClassName.bestGuess(i)));
170+
171+
b.addStatement("interceptors = $T.mergeLists(queryParamsToBodyInterceptor, interceptors)", CollectionUtils.class)
172+
.addStatement("interceptors = $T.mergeLists(customizationInterceptors, interceptors)", CollectionUtils.class);
173+
174+
return b.addStatement("clientConfiguration = clientConfiguration.toBuilder().option($T.EXECUTION_INTERCEPTORS, "
175+
+ "interceptors).build()", SdkClientOption.class);
142176
}
143177

144178
private MethodSpec bearerTokenProviderMethod() {

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

Lines changed: 4 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,6 @@
2828
import com.squareup.javapoet.TypeSpec;
2929
import com.squareup.javapoet.TypeVariableName;
3030
import java.util.ArrayList;
31-
import java.util.Collections;
3231
import java.util.List;
3332
import java.util.Map;
3433
import java.util.Optional;
@@ -59,7 +58,6 @@
5958
import software.amazon.awssdk.core.signer.Signer;
6059
import software.amazon.awssdk.http.Protocol;
6160
import software.amazon.awssdk.http.SdkHttpConfigurationOption;
62-
import software.amazon.awssdk.protocols.query.interceptor.QueryParametersToBodyInterceptor;
6361
import software.amazon.awssdk.utils.AttributeMap;
6462
import software.amazon.awssdk.utils.CollectionUtils;
6563
import software.amazon.awssdk.utils.StringUtils;
@@ -262,8 +260,10 @@ private MethodSpec finalizeServiceConfigurationMethod() {
262260
builtInInterceptors.add(endpointRulesSpecUtils.authSchemesInterceptorName());
263261
builtInInterceptors.add(endpointRulesSpecUtils.requestModifierInterceptorName());
264262

265-
for (String interceptor : model.getCustomizationConfig().getInterceptors()) {
266-
builtInInterceptors.add(ClassName.bestGuess(interceptor));
263+
if (!model.getMetadata().isQueryProtocol()) {
264+
for (String interceptor : model.getCustomizationConfig().getInterceptors()) {
265+
builtInInterceptors.add(ClassName.bestGuess(interceptor));
266+
}
267267
}
268268

269269
for (ClassName interceptor : builtInInterceptors) {
@@ -288,16 +288,6 @@ private MethodSpec finalizeServiceConfigurationMethod() {
288288
builder.addCode("interceptors = $T.mergeLists(interceptors, config.option($T.EXECUTION_INTERCEPTORS));\n",
289289
CollectionUtils.class, SdkClientOption.class);
290290

291-
if (model.getMetadata().isQueryProtocol()) {
292-
TypeName listType = ParameterizedTypeName.get(List.class, ExecutionInterceptor.class);
293-
builder.addStatement("$T protocolInterceptors = $T.singletonList(new $T())",
294-
listType,
295-
Collections.class,
296-
QueryParametersToBodyInterceptor.class);
297-
builder.addStatement("interceptors = $T.mergeLists(interceptors, protocolInterceptors)",
298-
CollectionUtils.class);
299-
}
300-
301291
if (model.getEndpointOperation().isPresent()) {
302292
builder.beginControlFlow("if (!endpointDiscoveryEnabled)")
303293
.addStatement("$1T chain = new $1T(config)", DefaultEndpointDiscoveryProviderChain.class)

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

Lines changed: 54 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -18,8 +18,12 @@
1818
import com.squareup.javapoet.ClassName;
1919
import com.squareup.javapoet.MethodSpec;
2020
import com.squareup.javapoet.ParameterizedTypeName;
21+
import com.squareup.javapoet.TypeName;
2122
import com.squareup.javapoet.TypeSpec;
2223
import java.net.URI;
24+
import java.util.ArrayList;
25+
import java.util.Collections;
26+
import java.util.List;
2327
import javax.lang.model.element.Modifier;
2428
import software.amazon.awssdk.annotations.SdkInternalApi;
2529
import software.amazon.awssdk.auth.token.credentials.SdkTokenProvider;
@@ -32,6 +36,9 @@
3236
import software.amazon.awssdk.codegen.utils.AuthUtils;
3337
import software.amazon.awssdk.core.client.config.SdkClientConfiguration;
3438
import software.amazon.awssdk.core.client.config.SdkClientOption;
39+
import software.amazon.awssdk.core.interceptor.ExecutionInterceptor;
40+
import software.amazon.awssdk.protocols.query.interceptor.QueryParametersToBodyInterceptor;
41+
import software.amazon.awssdk.utils.CollectionUtils;
3542

3643
public class SyncClientBuilderClass implements ClassSpec {
3744
private final IntermediateModel model;
@@ -119,26 +126,53 @@ private MethodSpec endpointProviderMethod() {
119126

120127

121128
private MethodSpec buildClientMethod() {
122-
return MethodSpec.methodBuilder("buildClient")
123-
.addAnnotation(Override.class)
124-
.addModifiers(Modifier.PROTECTED, Modifier.FINAL)
125-
.returns(clientInterfaceName)
126-
.addStatement("$T clientConfiguration = super.syncClientConfiguration()", SdkClientConfiguration.class)
127-
.addStatement("this.validateClientOptions(clientConfiguration)")
128-
.addStatement("$T endpointOverride = null", URI.class)
129-
.addCode("if (clientConfiguration.option($T.ENDPOINT_OVERRIDDEN) != null"
130-
+ "&& $T.TRUE.equals(clientConfiguration.option($T.ENDPOINT_OVERRIDDEN))) {"
131-
+ "endpointOverride = clientConfiguration.option($T.ENDPOINT);"
132-
+ "}",
133-
SdkClientOption.class, Boolean.class, SdkClientOption.class, SdkClientOption.class)
134-
.addStatement("$T serviceClientConfiguration = $T.builder()"
135-
+ ".overrideConfiguration(overrideConfiguration())"
136-
+ ".region(clientConfiguration.option($T.AWS_REGION))"
137-
+ ".endpointOverride(endpointOverride)"
138-
+ ".build()",
139-
serviceConfigClassName, serviceConfigClassName, AwsClientOption.class)
140-
.addStatement("return new $T(serviceClientConfiguration, clientConfiguration)", clientClassName)
141-
.build();
129+
MethodSpec.Builder b = MethodSpec.methodBuilder("buildClient")
130+
.addAnnotation(Override.class)
131+
.addModifiers(Modifier.PROTECTED, Modifier.FINAL)
132+
.returns(clientInterfaceName)
133+
.addStatement("$T clientConfiguration = super.syncClientConfiguration()",
134+
SdkClientConfiguration.class);
135+
136+
addQueryProtocolInterceptors(b);
137+
138+
return b.addStatement("this.validateClientOptions(clientConfiguration)")
139+
.addStatement("$T endpointOverride = null", URI.class)
140+
.addCode("if (clientConfiguration.option($T.ENDPOINT_OVERRIDDEN) != null"
141+
+ "&& $T.TRUE.equals(clientConfiguration.option($T.ENDPOINT_OVERRIDDEN))) {"
142+
+ "endpointOverride = clientConfiguration.option($T.ENDPOINT);"
143+
+ "}",
144+
SdkClientOption.class, Boolean.class, SdkClientOption.class, SdkClientOption.class)
145+
.addStatement("$T serviceClientConfiguration = $T.builder()"
146+
+ ".overrideConfiguration(overrideConfiguration())"
147+
+ ".region(clientConfiguration.option($T.AWS_REGION))"
148+
+ ".endpointOverride(endpointOverride)"
149+
+ ".build()",
150+
serviceConfigClassName, serviceConfigClassName, AwsClientOption.class)
151+
.addStatement("return new $T(serviceClientConfiguration, clientConfiguration)", clientClassName)
152+
.build();
153+
}
154+
155+
private MethodSpec.Builder addQueryProtocolInterceptors(MethodSpec.Builder b) {
156+
if (!model.getMetadata().isQueryProtocol()) {
157+
return b;
158+
}
159+
160+
TypeName listType = ParameterizedTypeName.get(List.class, ExecutionInterceptor.class);
161+
162+
b.addStatement("$T interceptors = clientConfiguration.option($T.EXECUTION_INTERCEPTORS)",
163+
listType, SdkClientOption.class)
164+
.addStatement("$T queryParamsToBodyInterceptor = $T.singletonList(new $T())",
165+
listType, Collections.class, QueryParametersToBodyInterceptor.class)
166+
.addStatement("$T customizationInterceptors = new $T<>()", listType, ArrayList.class);
167+
168+
List<String> customInterceptors = model.getCustomizationConfig().getInterceptors();
169+
customInterceptors.forEach(i -> b.addStatement("customizationInterceptors.add(new $T())", ClassName.bestGuess(i)));
170+
171+
b.addStatement("interceptors = $T.mergeLists(queryParamsToBodyInterceptor, interceptors)", CollectionUtils.class)
172+
.addStatement("interceptors = $T.mergeLists(customizationInterceptors, interceptors)", CollectionUtils.class);
173+
174+
return b.addStatement("clientConfiguration = clientConfiguration.toBuilder().option($T.EXECUTION_INTERCEPTORS, "
175+
+ "interceptors).build()", SdkClientOption.class);
142176
}
143177

144178
private MethodSpec tokenProviderMethodImpl() {
Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
package software.amazon.awssdk.codegen.internal;
2+
3+
import software.amazon.awssdk.annotations.SdkInternalApi;
4+
import software.amazon.awssdk.codegen.poet.builder.BuilderClassTest;
5+
6+
/**
7+
* Empty no-op test interceptor for query protocols to view generated code in test-query-sync-client-builder-class.java and
8+
* test-query-async-client-builder-class.java and validate in {@link BuilderClassTest}.
9+
*/
10+
@SdkInternalApi
11+
public class QueryProtocolCustomTestInterceptor {
12+
}

codegen/src/test/java/software/amazon/awssdk/codegen/poet/builder/BuilderClassTest.java

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -58,6 +58,16 @@ public void baseQueryClientBuilderClass() throws Exception {
5858
validateQueryGeneration(BaseClientBuilderClass::new, "test-query-client-builder-class.java");
5959
}
6060

61+
@Test
62+
public void syncQueryClientBuilderClass() throws Exception {
63+
validateQueryGeneration(SyncClientBuilderClass::new, "test-query-sync-client-builder-class.java");
64+
}
65+
66+
@Test
67+
public void asyncQueryClientBuilderClass() throws Exception {
68+
validateQueryGeneration(AsyncClientBuilderClass::new, "test-query-async-client-builder-class.java");
69+
}
70+
6171
@Test
6272
public void syncClientBuilderInterface() throws Exception {
6373
validateGeneration(SyncClientBuilderInterface::new, "test-sync-client-builder-interface.java");
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,61 @@
1+
package software.amazon.awssdk.services.query;
2+
3+
import java.net.URI;
4+
import java.util.ArrayList;
5+
import java.util.Collections;
6+
import java.util.List;
7+
import software.amazon.awssdk.annotations.Generated;
8+
import software.amazon.awssdk.annotations.SdkInternalApi;
9+
import software.amazon.awssdk.auth.token.credentials.SdkTokenProvider;
10+
import software.amazon.awssdk.awscore.client.config.AwsClientOption;
11+
import software.amazon.awssdk.codegen.internal.QueryProtocolCustomTestInterceptor;
12+
import software.amazon.awssdk.core.client.config.SdkClientConfiguration;
13+
import software.amazon.awssdk.core.client.config.SdkClientOption;
14+
import software.amazon.awssdk.core.interceptor.ExecutionInterceptor;
15+
import software.amazon.awssdk.protocols.query.interceptor.QueryParametersToBodyInterceptor;
16+
import software.amazon.awssdk.services.query.endpoints.QueryEndpointProvider;
17+
import software.amazon.awssdk.utils.CollectionUtils;
18+
19+
/**
20+
* Internal implementation of {@link QueryAsyncClientBuilder}.
21+
*/
22+
@Generated("software.amazon.awssdk:codegen")
23+
@SdkInternalApi
24+
final class DefaultQueryAsyncClientBuilder extends DefaultQueryBaseClientBuilder<QueryAsyncClientBuilder, QueryAsyncClient>
25+
implements QueryAsyncClientBuilder {
26+
@Override
27+
public DefaultQueryAsyncClientBuilder endpointProvider(QueryEndpointProvider endpointProvider) {
28+
clientConfiguration.option(SdkClientOption.ENDPOINT_PROVIDER, endpointProvider);
29+
return this;
30+
}
31+
32+
@Override
33+
public DefaultQueryAsyncClientBuilder tokenProvider(SdkTokenProvider tokenProvider) {
34+
clientConfiguration.option(AwsClientOption.TOKEN_PROVIDER, tokenProvider);
35+
return this;
36+
}
37+
38+
@Override
39+
protected final QueryAsyncClient buildClient() {
40+
SdkClientConfiguration clientConfiguration = super.asyncClientConfiguration();
41+
List<ExecutionInterceptor> interceptors = clientConfiguration.option(SdkClientOption.EXECUTION_INTERCEPTORS);
42+
List<ExecutionInterceptor> queryParamsToBodyInterceptor = Collections
43+
.singletonList(new QueryParametersToBodyInterceptor());
44+
List<ExecutionInterceptor> customizationInterceptors = new ArrayList<>();
45+
customizationInterceptors.add(new QueryProtocolCustomTestInterceptor());
46+
interceptors = CollectionUtils.mergeLists(queryParamsToBodyInterceptor, interceptors);
47+
interceptors = CollectionUtils.mergeLists(customizationInterceptors, interceptors);
48+
clientConfiguration = clientConfiguration.toBuilder().option(SdkClientOption.EXECUTION_INTERCEPTORS, interceptors)
49+
.build();
50+
this.validateClientOptions(clientConfiguration);
51+
URI endpointOverride = null;
52+
if (clientConfiguration.option(SdkClientOption.ENDPOINT_OVERRIDDEN) != null
53+
&& Boolean.TRUE.equals(clientConfiguration.option(SdkClientOption.ENDPOINT_OVERRIDDEN))) {
54+
endpointOverride = clientConfiguration.option(SdkClientOption.ENDPOINT);
55+
}
56+
QueryServiceClientConfiguration serviceClientConfiguration = QueryServiceClientConfiguration.builder()
57+
.overrideConfiguration(overrideConfiguration()).region(clientConfiguration.option(AwsClientOption.AWS_REGION))
58+
.endpointOverride(endpointOverride).build();
59+
return new DefaultQueryAsyncClient(serviceClientConfiguration, clientConfiguration);
60+
}
61+
}

0 commit comments

Comments
 (0)