Skip to content

Commit 1246c2a

Browse files
authored
Support for new HttpChecksum trait for requests and responses (#3038)
1 parent 03677b2 commit 1246c2a

File tree

103 files changed

+9830
-211
lines changed

Some content is hidden

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

103 files changed

+9830
-211
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": "Support adding http checksum for requests and validation of http checksum for responses based on HttpChecksum traits defined in the model."
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
@@ -164,6 +164,7 @@ public Map<String, OperationModel> constructOperations() {
164164
operationModel.setEndpointDiscovery(op.getEndpointdiscovery());
165165
operationModel.setEndpointTrait(op.getEndpoint());
166166
operationModel.setHttpChecksumRequired(op.isHttpChecksumRequired());
167+
operationModel.setHttpChecksum(op.getHttpChecksum());
167168

168169
Input input = op.getInput();
169170
if (input != null) {
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.checksum;
17+
18+
import java.util.List;
19+
import software.amazon.awssdk.annotations.SdkInternalApi;
20+
21+
/**
22+
* Class to map the HttpChecksum trait of an operation.
23+
*/
24+
@SdkInternalApi
25+
public class HttpChecksum {
26+
27+
private boolean requestChecksumRequired;
28+
29+
private String requestAlgorithmMember;
30+
31+
private String requestValidationModeMember;
32+
33+
private List<String> responseAlgorithms;
34+
35+
public boolean isRequestChecksumRequired() {
36+
return requestChecksumRequired;
37+
}
38+
39+
public void setRequestChecksumRequired(boolean requestChecksumRequired) {
40+
this.requestChecksumRequired = requestChecksumRequired;
41+
}
42+
43+
public String getRequestAlgorithmMember() {
44+
return requestAlgorithmMember;
45+
}
46+
47+
public void setRequestAlgorithmMember(String requestAlgorithmMember) {
48+
this.requestAlgorithmMember = requestAlgorithmMember;
49+
}
50+
51+
public String getRequestValidationModeMember() {
52+
return requestValidationModeMember;
53+
}
54+
55+
public void setRequestValidationModeMember(String requestValidationModeMember) {
56+
this.requestValidationModeMember = requestValidationModeMember;
57+
}
58+
59+
public List<String> getResponseAlgorithms() {
60+
return responseAlgorithms;
61+
}
62+
63+
public void setResponseAlgorithms(List<String> responseAlgorithms) {
64+
this.responseAlgorithms = responseAlgorithms;
65+
}
66+
}

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
@@ -18,6 +18,7 @@
1818
import com.fasterxml.jackson.annotation.JsonIgnore;
1919
import java.util.ArrayList;
2020
import java.util.List;
21+
import software.amazon.awssdk.codegen.checksum.HttpChecksum;
2122
import software.amazon.awssdk.codegen.docs.ClientType;
2223
import software.amazon.awssdk.codegen.docs.DocConfiguration;
2324
import software.amazon.awssdk.codegen.docs.OperationDocs;
@@ -66,6 +67,8 @@ public class OperationModel extends DocumentationModel {
6667

6768
private boolean httpChecksumRequired;
6869

70+
private HttpChecksum httpChecksum;
71+
6972
public String getOperationName() {
7073
return operationName;
7174
}
@@ -292,4 +295,12 @@ public boolean isHttpChecksumRequired() {
292295
public void setHttpChecksumRequired(boolean httpChecksumRequired) {
293296
this.httpChecksumRequired = httpChecksumRequired;
294297
}
298+
299+
public HttpChecksum getHttpChecksum() {
300+
return httpChecksum;
301+
}
302+
303+
public void setHttpChecksum(HttpChecksum httpChecksum) {
304+
this.httpChecksum = httpChecksum;
305+
}
295306
}

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
@@ -16,6 +16,7 @@
1616
package software.amazon.awssdk.codegen.model.service;
1717

1818
import java.util.List;
19+
import software.amazon.awssdk.codegen.checksum.HttpChecksum;
1920
import software.amazon.awssdk.codegen.model.intermediate.EndpointDiscovery;
2021

2122
public class Operation {
@@ -48,6 +49,8 @@ public class Operation {
4849

4950
private boolean httpChecksumRequired;
5051

52+
private HttpChecksum httpChecksum;
53+
5154
public String getName() {
5255
return name;
5356
}
@@ -174,4 +177,12 @@ public boolean isHttpChecksumRequired() {
174177
public void setHttpChecksumRequired(boolean httpChecksumRequired) {
175178
this.httpChecksumRequired = httpChecksumRequired;
176179
}
180+
181+
public HttpChecksum getHttpChecksum() {
182+
return httpChecksum;
183+
}
184+
185+
public void setHttpChecksum(HttpChecksum httpChecksum) {
186+
this.httpChecksum = httpChecksum;
187+
}
177188
}

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
@@ -40,6 +40,7 @@
4040
import software.amazon.awssdk.codegen.model.intermediate.ShapeModel;
4141
import software.amazon.awssdk.codegen.poet.PoetExtensions;
4242
import software.amazon.awssdk.codegen.poet.client.traits.HttpChecksumRequiredTrait;
43+
import software.amazon.awssdk.codegen.poet.client.traits.HttpChecksumTrait;
4344
import software.amazon.awssdk.codegen.poet.eventstream.EventStreamUtils;
4445
import software.amazon.awssdk.codegen.poet.model.EventStreamSpecHelper;
4546
import software.amazon.awssdk.core.SdkPojoBuilder;
@@ -175,7 +176,8 @@ public CodeBlock executionHandler(OperationModel opModel) {
175176
.add(discoveredEndpoint(opModel))
176177
.add(".withInput($L)\n", opModel.getInput().getVariableName())
177178
.add(".withMetricCollector(apiCallMetricCollector)")
178-
.add(HttpChecksumRequiredTrait.putHttpChecksumAttribute(opModel));
179+
.add(HttpChecksumRequiredTrait.putHttpChecksumAttribute(opModel))
180+
.add(HttpChecksumTrait.create(opModel));
179181

180182
if (opModel.hasStreamingInput()) {
181183
codeBlock.add(".withRequestBody(requestBody)")
@@ -242,6 +244,7 @@ public CodeBlock asyncExecutionHandler(IntermediateModel intermediateModel, Oper
242244
.add(discoveredEndpoint(opModel))
243245
.add(asyncRequestBody)
244246
.add(HttpChecksumRequiredTrait.putHttpChecksumAttribute(opModel))
247+
.add(HttpChecksumTrait.create(opModel))
245248
.add(".withInput($L)$L);",
246249
opModel.getInput().getVariableName(), asyncResponseTransformerVariable(isStreaming, isRestJson, opModel));
247250

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
@@ -29,6 +29,7 @@
2929
import software.amazon.awssdk.codegen.model.intermediate.OperationModel;
3030
import software.amazon.awssdk.codegen.poet.PoetExtensions;
3131
import software.amazon.awssdk.codegen.poet.client.traits.HttpChecksumRequiredTrait;
32+
import software.amazon.awssdk.codegen.poet.client.traits.HttpChecksumTrait;
3233
import software.amazon.awssdk.core.async.AsyncResponseTransformer;
3334
import software.amazon.awssdk.core.client.handler.ClientExecutionParams;
3435
import software.amazon.awssdk.core.http.HttpResponseHandler;
@@ -111,7 +112,8 @@ public CodeBlock executionHandler(OperationModel opModel) {
111112
.add(discoveredEndpoint(opModel))
112113
.add(".withInput($L)", opModel.getInput().getVariableName())
113114
.add(".withMetricCollector(apiCallMetricCollector)")
114-
.add(HttpChecksumRequiredTrait.putHttpChecksumAttribute(opModel));
115+
.add(HttpChecksumRequiredTrait.putHttpChecksumAttribute(opModel))
116+
.add(HttpChecksumTrait.create(opModel));
115117

116118
if (opModel.hasStreamingInput()) {
117119
return codeBlock.add(".withRequestBody(requestBody)")
@@ -142,7 +144,8 @@ public CodeBlock asyncExecutionHandler(IntermediateModel intermediateModel, Oper
142144
.add(".withResponseHandler(responseHandler)\n")
143145
.add(".withErrorResponseHandler(errorResponseHandler)\n")
144146
.add(".withMetricCollector(apiCallMetricCollector)\n")
145-
.add(HttpChecksumRequiredTrait.putHttpChecksumAttribute(opModel));
147+
.add(HttpChecksumRequiredTrait.putHttpChecksumAttribute(opModel))
148+
.add(HttpChecksumTrait.create(opModel));
146149

147150
builder.add(hostPrefixExpression(opModel) + asyncRequestBody + ".withInput($L)$L);",
148151
opModel.getInput().getVariableName(),

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
@@ -35,6 +35,7 @@
3535
import software.amazon.awssdk.codegen.model.intermediate.ShapeModel;
3636
import software.amazon.awssdk.codegen.poet.PoetExtensions;
3737
import software.amazon.awssdk.codegen.poet.client.traits.HttpChecksumRequiredTrait;
38+
import software.amazon.awssdk.codegen.poet.client.traits.HttpChecksumTrait;
3839
import software.amazon.awssdk.codegen.poet.eventstream.EventStreamUtils;
3940
import software.amazon.awssdk.codegen.poet.model.EventStreamSpecHelper;
4041
import software.amazon.awssdk.core.SdkPojoBuilder;
@@ -130,7 +131,8 @@ public CodeBlock executionHandler(OperationModel opModel) {
130131
hostPrefixExpression(opModel) +
131132
discoveredEndpoint(opModel))
132133
.add(".withInput($L)", opModel.getInput().getVariableName())
133-
.add(HttpChecksumRequiredTrait.putHttpChecksumAttribute(opModel));
134+
.add(HttpChecksumRequiredTrait.putHttpChecksumAttribute(opModel))
135+
.add(HttpChecksumTrait.create(opModel));
134136

135137
s3ArnableFields(opModel, model).ifPresent(codeBlock::add);
136138

@@ -204,7 +206,8 @@ public CodeBlock asyncExecutionHandler(IntermediateModel intermediateModel, Oper
204206
builder.add(hostPrefixExpression(opModel))
205207
.add(".withMetricCollector(apiCallMetricCollector)\n")
206208
.add(asyncRequestBody(opModel))
207-
.add(HttpChecksumRequiredTrait.putHttpChecksumAttribute(opModel));
209+
.add(HttpChecksumRequiredTrait.putHttpChecksumAttribute(opModel))
210+
.add(HttpChecksumTrait.create(opModel));
208211

209212
s3ArnableFields(opModel, model).ifPresent(builder::add);
210213

Lines changed: 97 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,97 @@
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.MemberModel;
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.interceptor.trait.HttpChecksum;
26+
27+
/**
28+
* The logic for handling the Flexible "httpChecksum" trait within the code generator.
29+
*/
30+
public class HttpChecksumTrait {
31+
32+
private HttpChecksumTrait() {
33+
}
34+
35+
36+
/**
37+
* Generate a ".putExecutionAttribute(...)" code-block for the provided operation model. This should be used within the
38+
* context of initializing {@link ClientExecutionParams}.
39+
* If HTTP checksums are not required by the operation, this will return an empty code-block.
40+
*/
41+
public static CodeBlock create(OperationModel operationModel) {
42+
43+
if (operationModel.getHttpChecksum() != null) {
44+
45+
CodeBlock.Builder codeBuilder = CodeBlock.builder();
46+
codeBuilder.add(CodeBlock.of(".putExecutionAttribute($T.HTTP_CHECKSUM, $T.builder().requestChecksumRequired($L)",
47+
SdkInternalExecutionAttribute.class, HttpChecksum.class,
48+
operationModel.getHttpChecksum().isRequestChecksumRequired()));
49+
50+
addFluentGetterToBuilder(operationModel,
51+
codeBuilder,
52+
operationModel.getHttpChecksum().getRequestAlgorithmMember(),
53+
"requestAlgorithm");
54+
55+
addFluentGetterToBuilder(operationModel,
56+
codeBuilder,
57+
operationModel.getHttpChecksum().getRequestValidationModeMember(),
58+
"requestValidationMode");
59+
60+
// loop to get the comma separated strings \"literals\"
61+
List<String> responseAlgorithms = operationModel.getHttpChecksum().getResponseAlgorithms();
62+
if (responseAlgorithms != null && !responseAlgorithms.isEmpty()) {
63+
64+
codeBuilder.add(CodeBlock.of(".responseAlgorithms("))
65+
.add(
66+
CodeBlock.of("$L",
67+
responseAlgorithms.stream().collect(
68+
Collectors.joining("\", \"", "\"", "\""))))
69+
.add(CodeBlock.of(")"));
70+
}
71+
codeBuilder.add(CodeBlock.of(".isRequestStreaming($L)", operationModel.getInputShape().isHasStreamingMember()));
72+
return codeBuilder.add(CodeBlock.of(".build())")).build();
73+
} else {
74+
return CodeBlock.of("");
75+
}
76+
}
77+
78+
private static void addFluentGetterToBuilder(OperationModel operationModel, CodeBlock.Builder codeBuilder,
79+
String requestValidationModeMemberInModel, String memberBuilderName) {
80+
81+
if (requestValidationModeMemberInModel != null) {
82+
MemberModel requestValidationModeMember =
83+
operationModel.getInputShape().tryFindMemberModelByC2jName(
84+
requestValidationModeMemberInModel, true);
85+
86+
if (requestValidationModeMember == null) {
87+
throw new IllegalStateException(requestValidationModeMemberInModel
88+
+ " is not a member in "
89+
+ operationModel.getInputShape().getShapeName());
90+
}
91+
codeBuilder.add(".$L($N.$N())",
92+
memberBuilderName,
93+
operationModel.getInput().getVariableName(),
94+
requestValidationModeMember.getFluentGetterMethodName());
95+
}
96+
}
97+
}

codegen/src/test/java/software/amazon/awssdk/codegen/poet/client/PoetClientFunctionalTests.java

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,6 @@
2525
import software.amazon.awssdk.codegen.poet.ClientTestModels;
2626

2727
public class PoetClientFunctionalTests {
28-
2928
@Test
3029
public void asyncClientClass() throws Exception {
3130
AsyncClientClass asyncClientClass = createAsyncClientClass(ClientTestModels.restJsonServiceModels());
@@ -41,7 +40,7 @@ public void asyncClientInterface() throws Exception {
4140
@Test
4241
public void simpleMethodsIntegClass() throws Exception {
4342
ClientSimpleMethodsIntegrationTests simpleMethodsClass = new ClientSimpleMethodsIntegrationTests(
44-
ClientTestModels.restJsonServiceModels());
43+
ClientTestModels.restJsonServiceModels());
4544
assertThat(simpleMethodsClass, generatesTo("test-simple-methods-integ-class.java"));
4645
}
4746

@@ -104,14 +103,14 @@ public void syncClientEndpointDiscovery() throws Exception {
104103
@Test
105104
public void asyncClientEndpointDiscovery() throws Exception {
106105
ClassSpec asyncClientEndpointDiscovery = new AsyncClientClass(
107-
GeneratorTaskParams.create(ClientTestModels.endpointDiscoveryModels(), "sources/", "tests/"));
106+
GeneratorTaskParams.create(ClientTestModels.endpointDiscoveryModels(), "sources/", "tests/"));
108107
assertThat(asyncClientEndpointDiscovery, generatesTo("test-endpoint-discovery-async.java"));
109108
}
110109

111110
@Test
112111
public void asyncClientCustomServiceMetaData() throws Exception {
113112
ClassSpec asyncClientCustomServiceMetaData = new AsyncClientClass(
114-
GeneratorTaskParams.create(ClientTestModels.customContentTypeModels(), "sources/", "tests/"));
113+
GeneratorTaskParams.create(ClientTestModels.customContentTypeModels(), "sources/", "tests/"));
115114
assertThat(asyncClientCustomServiceMetaData, generatesTo("test-customservicemetadata-async.java"));
116115
}
117116

@@ -120,4 +119,5 @@ public void syncClientCustomServiceMetaData() throws Exception {
120119
ClassSpec syncClientCustomServiceMetaData = createSyncClientClass(ClientTestModels.customContentTypeModels());
121120
assertThat(syncClientCustomServiceMetaData, generatesTo("test-customservicemetadata-sync.java"));
122121
}
122+
123123
}

0 commit comments

Comments
 (0)