Skip to content

Commit 7e19edd

Browse files
authored
Request compression: non-streaming operations (#4193)
* Adding codegen updates and configuration options (#4085) * Adding configuration options * Adding codegen updates * Adding javadocs * Fix CheckStyle/SpotBugs errors, and add RequestCompression interceptor trait and SdkInternalExecutionAttribute * RequestCompression interceptor trait * Refactoring, adding profile config and javadocs * Refactoring and add codegen tests * Add codegen tests * Update code generated test classes * Request compression - nonstreaming operations * Throw codegen error for streaming operations with request compression * Throw codegen error for S3 operations with request compression * Changelog entry * Refactoring * Refactoring * Move interceptor trait to internal module * Update javadoc * Move config resolution logic to SdkDefaultClientBuilder * Null check for clientOverrideConfiguration * Remove unnecessary ExecutionAttribute
1 parent 233668b commit 7e19edd

File tree

46 files changed

+2077
-27
lines changed

Some content is hidden

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

46 files changed

+2077
-27
lines changed
Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
{
2+
"category": "AWS SDK for Java v2",
3+
"contributor": "",
4+
"type": "feature",
5+
"description": "Adding support for \"requestCompression\" trait to GZIP compress payloads for non-streaming operations."
6+
}

codegen/src/main/java/software/amazon/awssdk/codegen/AddOperations.java

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -165,6 +165,7 @@ public Map<String, OperationModel> constructOperations() {
165165
operationModel.setEndpointTrait(op.getEndpoint());
166166
operationModel.setHttpChecksumRequired(op.isHttpChecksumRequired());
167167
operationModel.setHttpChecksum(op.getHttpChecksum());
168+
operationModel.setRequestCompression(op.getRequestCompression());
168169
operationModel.setStaticContextParams(op.getStaticContextParams());
169170

170171
Input input = op.getInput();
Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
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.compression;
17+
18+
import java.util.List;
19+
import software.amazon.awssdk.annotations.SdkInternalApi;
20+
21+
/**
22+
* Class to map the RequestCompression trait of an operation.
23+
*/
24+
@SdkInternalApi
25+
public class RequestCompression {
26+
27+
private List<String> encodings;
28+
29+
public List<String> getEncodings() {
30+
return encodings;
31+
}
32+
33+
public void setEncodings(List<String> encodings) {
34+
this.encodings = encodings;
35+
}
36+
}

codegen/src/main/java/software/amazon/awssdk/codegen/model/intermediate/OperationModel.java

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@
2020
import java.util.List;
2121
import java.util.Map;
2222
import software.amazon.awssdk.codegen.checksum.HttpChecksum;
23+
import software.amazon.awssdk.codegen.compression.RequestCompression;
2324
import software.amazon.awssdk.codegen.docs.ClientType;
2425
import software.amazon.awssdk.codegen.docs.DocConfiguration;
2526
import software.amazon.awssdk.codegen.docs.OperationDocs;
@@ -71,6 +72,8 @@ public class OperationModel extends DocumentationModel {
7172

7273
private HttpChecksum httpChecksum;
7374

75+
private RequestCompression requestCompression;
76+
7477
@JsonIgnore
7578
private Map<String, StaticContextParam> staticContextParams;
7679

@@ -309,6 +312,14 @@ public void setHttpChecksum(HttpChecksum httpChecksum) {
309312
this.httpChecksum = httpChecksum;
310313
}
311314

315+
public RequestCompression getRequestCompression() {
316+
return requestCompression;
317+
}
318+
319+
public void setRequestCompression(RequestCompression requestCompression) {
320+
this.requestCompression = requestCompression;
321+
}
322+
312323
public Map<String, StaticContextParam> getStaticContextParams() {
313324
return staticContextParams;
314325
}

codegen/src/main/java/software/amazon/awssdk/codegen/model/service/Operation.java

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@
1818
import java.util.List;
1919
import java.util.Map;
2020
import software.amazon.awssdk.codegen.checksum.HttpChecksum;
21+
import software.amazon.awssdk.codegen.compression.RequestCompression;
2122
import software.amazon.awssdk.codegen.model.intermediate.EndpointDiscovery;
2223

2324
public class Operation {
@@ -52,6 +53,8 @@ public class Operation {
5253

5354
private HttpChecksum httpChecksum;
5455

56+
private RequestCompression requestCompression;
57+
5558
private Map<String, StaticContextParam> staticContextParams;
5659

5760
public String getName() {
@@ -189,6 +192,14 @@ public void setHttpChecksum(HttpChecksum httpChecksum) {
189192
this.httpChecksum = httpChecksum;
190193
}
191194

195+
public RequestCompression getRequestCompression() {
196+
return requestCompression;
197+
}
198+
199+
public void setRequestCompression(RequestCompression requestCompression) {
200+
this.requestCompression = requestCompression;
201+
}
202+
192203
public Map<String, StaticContextParam> getStaticContextParams() {
193204
return staticContextParams;
194205
}

codegen/src/main/java/software/amazon/awssdk/codegen/poet/client/specs/JsonProtocolSpec.java

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -42,6 +42,7 @@
4242
import software.amazon.awssdk.codegen.poet.client.traits.HttpChecksumRequiredTrait;
4343
import software.amazon.awssdk.codegen.poet.client.traits.HttpChecksumTrait;
4444
import software.amazon.awssdk.codegen.poet.client.traits.NoneAuthTypeRequestTrait;
45+
import software.amazon.awssdk.codegen.poet.client.traits.RequestCompressionTrait;
4546
import software.amazon.awssdk.codegen.poet.eventstream.EventStreamUtils;
4647
import software.amazon.awssdk.codegen.poet.model.EventStreamSpecHelper;
4748
import software.amazon.awssdk.core.SdkPojoBuilder;
@@ -187,7 +188,8 @@ public CodeBlock executionHandler(OperationModel opModel) {
187188
.add(".withMetricCollector(apiCallMetricCollector)")
188189
.add(HttpChecksumRequiredTrait.putHttpChecksumAttribute(opModel))
189190
.add(HttpChecksumTrait.create(opModel))
190-
.add(NoneAuthTypeRequestTrait.create(opModel));
191+
.add(NoneAuthTypeRequestTrait.create(opModel))
192+
.add(RequestCompressionTrait.create(opModel, model));
191193

192194
if (opModel.hasStreamingInput()) {
193195
codeBlock.add(".withRequestBody(requestBody)")
@@ -257,6 +259,7 @@ public CodeBlock asyncExecutionHandler(IntermediateModel intermediateModel, Oper
257259
.add(HttpChecksumRequiredTrait.putHttpChecksumAttribute(opModel))
258260
.add(HttpChecksumTrait.create(opModel))
259261
.add(NoneAuthTypeRequestTrait.create(opModel))
262+
.add(RequestCompressionTrait.create(opModel, model))
260263
.add(".withInput($L)$L);",
261264
opModel.getInput().getVariableName(), asyncResponseTransformerVariable(isStreaming, isRestJson, opModel));
262265

codegen/src/main/java/software/amazon/awssdk/codegen/poet/client/specs/QueryProtocolSpec.java

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,7 @@
3131
import software.amazon.awssdk.codegen.poet.client.traits.HttpChecksumRequiredTrait;
3232
import software.amazon.awssdk.codegen.poet.client.traits.HttpChecksumTrait;
3333
import software.amazon.awssdk.codegen.poet.client.traits.NoneAuthTypeRequestTrait;
34+
import software.amazon.awssdk.codegen.poet.client.traits.RequestCompressionTrait;
3435
import software.amazon.awssdk.core.async.AsyncResponseTransformer;
3536
import software.amazon.awssdk.core.client.handler.ClientExecutionParams;
3637
import software.amazon.awssdk.core.http.HttpResponseHandler;
@@ -116,7 +117,8 @@ public CodeBlock executionHandler(OperationModel opModel) {
116117
.add(".withMetricCollector(apiCallMetricCollector)")
117118
.add(HttpChecksumRequiredTrait.putHttpChecksumAttribute(opModel))
118119
.add(HttpChecksumTrait.create(opModel))
119-
.add(NoneAuthTypeRequestTrait.create(opModel));
120+
.add(NoneAuthTypeRequestTrait.create(opModel))
121+
.add(RequestCompressionTrait.create(opModel, intermediateModel));
120122

121123

122124
if (opModel.hasStreamingInput()) {
@@ -151,7 +153,8 @@ public CodeBlock asyncExecutionHandler(IntermediateModel intermediateModel, Oper
151153
.add(".withMetricCollector(apiCallMetricCollector)\n")
152154
.add(HttpChecksumRequiredTrait.putHttpChecksumAttribute(opModel))
153155
.add(HttpChecksumTrait.create(opModel))
154-
.add(NoneAuthTypeRequestTrait.create(opModel));
156+
.add(NoneAuthTypeRequestTrait.create(opModel))
157+
.add(RequestCompressionTrait.create(opModel, intermediateModel));
155158

156159

157160
builder.add(hostPrefixExpression(opModel) + asyncRequestBody + ".withInput($L)$L);",

codegen/src/main/java/software/amazon/awssdk/codegen/poet/client/specs/XmlProtocolSpec.java

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,7 @@
3737
import software.amazon.awssdk.codegen.poet.client.traits.HttpChecksumRequiredTrait;
3838
import software.amazon.awssdk.codegen.poet.client.traits.HttpChecksumTrait;
3939
import software.amazon.awssdk.codegen.poet.client.traits.NoneAuthTypeRequestTrait;
40+
import software.amazon.awssdk.codegen.poet.client.traits.RequestCompressionTrait;
4041
import software.amazon.awssdk.codegen.poet.eventstream.EventStreamUtils;
4142
import software.amazon.awssdk.codegen.poet.model.EventStreamSpecHelper;
4243
import software.amazon.awssdk.core.SdkPojoBuilder;
@@ -135,7 +136,8 @@ public CodeBlock executionHandler(OperationModel opModel) {
135136
.add(".withInput($L)", opModel.getInput().getVariableName())
136137
.add(HttpChecksumRequiredTrait.putHttpChecksumAttribute(opModel))
137138
.add(HttpChecksumTrait.create(opModel))
138-
.add(NoneAuthTypeRequestTrait.create(opModel));
139+
.add(NoneAuthTypeRequestTrait.create(opModel))
140+
.add(RequestCompressionTrait.create(opModel, model));
139141

140142

141143
s3ArnableFields(opModel, model).ifPresent(codeBlock::add);
@@ -213,7 +215,8 @@ public CodeBlock asyncExecutionHandler(IntermediateModel intermediateModel, Oper
213215
.add(asyncRequestBody(opModel))
214216
.add(HttpChecksumRequiredTrait.putHttpChecksumAttribute(opModel))
215217
.add(HttpChecksumTrait.create(opModel))
216-
.add(NoneAuthTypeRequestTrait.create(opModel));
218+
.add(NoneAuthTypeRequestTrait.create(opModel))
219+
.add(RequestCompressionTrait.create(opModel, model));
217220

218221
s3ArnableFields(opModel, model).ifPresent(builder::add);
219222

Lines changed: 66 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,66 @@
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.client.traits;
17+
18+
import com.squareup.javapoet.CodeBlock;
19+
import java.util.List;
20+
import java.util.stream.Collectors;
21+
import software.amazon.awssdk.codegen.model.intermediate.IntermediateModel;
22+
import software.amazon.awssdk.codegen.model.intermediate.OperationModel;
23+
import software.amazon.awssdk.core.client.handler.ClientExecutionParams;
24+
import software.amazon.awssdk.core.interceptor.SdkInternalExecutionAttribute;
25+
import software.amazon.awssdk.core.internal.interceptor.trait.RequestCompression;
26+
27+
/**
28+
* The logic for handling the "requestCompression" trait within the code generator.
29+
*/
30+
public class RequestCompressionTrait {
31+
32+
private RequestCompressionTrait() {
33+
}
34+
35+
/**
36+
* Generate a ".putExecutionAttribute(...)" code-block for the provided operation model. This should be used within the
37+
* context of initializing {@link ClientExecutionParams}. If request compression is not required by the operation, this will
38+
* return an empty code-block.
39+
*/
40+
public static CodeBlock create(OperationModel operationModel, IntermediateModel model) {
41+
if (operationModel.getRequestCompression() == null) {
42+
return CodeBlock.of("");
43+
}
44+
45+
// TODO : remove once request compression for streaming operations is supported
46+
if (operationModel.isStreaming()) {
47+
throw new IllegalStateException("Request compression for streaming operations is not yet supported in the AWS SDK "
48+
+ "for Java.");
49+
}
50+
51+
// TODO : remove once S3 checksum interceptors are moved to occur after CompressRequestStage
52+
if (model.getMetadata().getServiceName().equals("S3")) {
53+
throw new IllegalStateException("Request compression for S3 is not yet supported in the AWS SDK for Java.");
54+
}
55+
56+
List<String> encodings = operationModel.getRequestCompression().getEncodings();
57+
58+
return CodeBlock.builder()
59+
.add(CodeBlock.of(".putExecutionAttribute($T.REQUEST_COMPRESSION, "
60+
+ "$T.builder().encodings($L).isStreaming($L).build())",
61+
SdkInternalExecutionAttribute.class, RequestCompression.class,
62+
encodings.stream().collect(Collectors.joining("\", \"", "\"", "\"")),
63+
operationModel.hasStreamingInput()))
64+
.build();
65+
}
66+
}

codegen/src/test/resources/software/amazon/awssdk/codegen/poet/client/c2j/json/service-2.json

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,16 @@
3030
},
3131
"authtype": "none"
3232
},
33+
"OperationWithRequestCompression": {
34+
"name": "APostOperation",
35+
"http": {
36+
"method": "POST",
37+
"requestUri": "/"
38+
},
39+
"requestCompression": {
40+
"encodings": ["gzip"]
41+
}
42+
},
3343
"APostOperation": {
3444
"name": "APostOperation",
3545
"http": {

codegen/src/test/resources/software/amazon/awssdk/codegen/poet/client/c2j/query/service-2.json

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -59,6 +59,16 @@
5959
},
6060
"authtype": "none"
6161
},
62+
"OperationWithRequestCompression": {
63+
"name": "APostOperation",
64+
"http": {
65+
"method": "POST",
66+
"requestUri": "/"
67+
},
68+
"requestCompression": {
69+
"encodings": ["gzip"]
70+
}
71+
},
6272
"APostOperation": {
6373
"name": "APostOperation",
6474
"http": {

codegen/src/test/resources/software/amazon/awssdk/codegen/poet/client/c2j/rest-json/service-2.json

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,16 @@
2222
},
2323
"httpChecksumRequired": true
2424
},
25+
"OperationWithRequestCompression": {
26+
"name": "APostOperation",
27+
"http": {
28+
"method": "POST",
29+
"requestUri": "/"
30+
},
31+
"requestCompression": {
32+
"encodings": ["gzip"]
33+
}
34+
},
2535
"APostOperation": {
2636
"name": "APostOperation",
2737
"http": {

codegen/src/test/resources/software/amazon/awssdk/codegen/poet/client/c2j/xml/service-2.json

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,16 @@
2929
},
3030
"authtype": "none"
3131
},
32+
"OperationWithRequestCompression": {
33+
"name": "APostOperation",
34+
"http": {
35+
"method": "POST",
36+
"requestUri": "/"
37+
},
38+
"requestCompression": {
39+
"encodings": ["gzip"]
40+
}
41+
},
3242
"APostOperation": {
3343
"name": "APostOperation",
3444
"http": {

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

Lines changed: 30 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,8 @@
2929
import software.amazon.awssdk.services.json.model.JsonRequest;
3030
import software.amazon.awssdk.services.json.model.OperationWithChecksumRequiredRequest;
3131
import software.amazon.awssdk.services.json.model.OperationWithChecksumRequiredResponse;
32+
import software.amazon.awssdk.services.json.model.OperationWithRequestCompressionRequest;
33+
import software.amazon.awssdk.services.json.model.OperationWithRequestCompressionResponse;
3234
import software.amazon.awssdk.services.json.model.PaginatedOperationWithResultKeyRequest;
3335
import software.amazon.awssdk.services.json.model.PaginatedOperationWithResultKeyResponse;
3436
import software.amazon.awssdk.services.json.model.PaginatedOperationWithoutResultKeyRequest;
@@ -305,6 +307,33 @@ public CompletableFuture<OperationWithChecksumRequiredResponse> operationWithChe
305307
return invokeOperation(operationWithChecksumRequiredRequest, request -> delegate.operationWithChecksumRequired(request));
306308
}
307309

310+
/**
311+
* Invokes the OperationWithRequestCompression operation asynchronously.
312+
*
313+
* @param operationWithRequestCompressionRequest
314+
* @return A Java Future containing the result of the OperationWithRequestCompression operation returned by the
315+
* service.<br/>
316+
* The CompletableFuture returned by this method can be completed exceptionally with the following
317+
* exceptions.
318+
* <ul>
319+
* <li>SdkException Base class for all exceptions that can be thrown by the SDK (both service and client).
320+
* Can be used for catch all scenarios.</li>
321+
* <li>SdkClientException If any client side error occurs such as an IO related failure, failure to get
322+
* credentials, etc.</li>
323+
* <li>JsonException Base class for all service exceptions. Unknown exceptions will be thrown as an instance
324+
* of this type.</li>
325+
* </ul>
326+
* @sample JsonAsyncClient.OperationWithRequestCompression
327+
* @see <a href="https://docs.aws.amazon.com/goto/WebAPI/json-service-2010-05-08/OperationWithRequestCompression"
328+
* target="_top">AWS API Documentation</a>
329+
*/
330+
@Override
331+
public CompletableFuture<OperationWithRequestCompressionResponse> operationWithRequestCompression(
332+
OperationWithRequestCompressionRequest operationWithRequestCompressionRequest) {
333+
return invokeOperation(operationWithRequestCompressionRequest,
334+
request -> delegate.operationWithRequestCompression(request));
335+
}
336+
308337
/**
309338
* Some paginated operation with result_key in paginators.json file
310339
*
@@ -468,7 +497,7 @@ public <ReturnT> CompletableFuture<ReturnT> streamingInputOutputOperation(
468497
StreamingInputOutputOperationRequest streamingInputOutputOperationRequest, AsyncRequestBody requestBody,
469498
AsyncResponseTransformer<StreamingInputOutputOperationResponse, ReturnT> asyncResponseTransformer) {
470499
return invokeOperation(streamingInputOutputOperationRequest,
471-
request -> delegate.streamingInputOutputOperation(request, requestBody, asyncResponseTransformer));
500+
request -> delegate.streamingInputOutputOperation(request, requestBody, asyncResponseTransformer));
472501
}
473502

474503
/**

0 commit comments

Comments
 (0)