Skip to content

Commit 1b33bdc

Browse files
authored
Add PartType field to UploadPartRequest (#3755)
* Add PartType field to UploadPartRequest * Addressing comments * Add synthetic field to custom shapes and exclude from SdkFields * Add tests and refactor * Add codegen tests * Add javadocs for synthetic field * Fix test issues * Add test to verify payload does not include injected shape * Refactoring to address comments * Fix CodeSmells
1 parent e57854b commit 1b33bdc

File tree

16 files changed

+582
-3
lines changed

16 files changed

+582
-3
lines changed
Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
{
2+
"category": "Amazon S3",
3+
"contributor": "",
4+
"type": "feature",
5+
"description": "Adding PartType field to UploadPartRequest to indicate whether the part is the last part or not."
6+
}

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

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -194,6 +194,7 @@ private MemberModel generateMemberModel(String c2jMemberName, Member c2jMemberDe
194194
memberModel.setUnionEnumTypeName(namingStrategy.getUnionEnumTypeName(memberModel));
195195
memberModel.setContextParam(c2jMemberDefinition.getContextParam());
196196
memberModel.setRequired(isRequiredMember(c2jMemberName, parentShape));
197+
memberModel.setSynthetic(shape.isSynthetic());
197198

198199

199200
// Pass the xmlNameSpace from the member reference
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,50 @@
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.customization.processors;
17+
18+
import java.util.Map;
19+
import software.amazon.awssdk.codegen.customization.CodegenCustomizationProcessor;
20+
import software.amazon.awssdk.codegen.model.config.customization.CustomSdkShapes;
21+
import software.amazon.awssdk.codegen.model.intermediate.IntermediateModel;
22+
import software.amazon.awssdk.codegen.model.service.ServiceModel;
23+
import software.amazon.awssdk.codegen.model.service.Shape;
24+
25+
public class CustomSdkShapesProcessor implements CodegenCustomizationProcessor {
26+
27+
private final CustomSdkShapes customSdkShapes;
28+
29+
CustomSdkShapesProcessor(CustomSdkShapes customSdkShapes) {
30+
this.customSdkShapes = customSdkShapes;
31+
}
32+
33+
@Override
34+
public void preprocess(ServiceModel serviceModel) {
35+
if (customSdkShapes == null) {
36+
return;
37+
}
38+
Map<String, Shape> shapes = serviceModel.getShapes();
39+
customSdkShapes.getShapes().forEach((shapeName, shape) -> {
40+
shape.setSynthetic(true);
41+
shapes.put(shapeName, shape);
42+
});
43+
serviceModel.setShapes(shapes);
44+
}
45+
46+
@Override
47+
public void postprocess(IntermediateModel intermediateModel) {
48+
// added custom shapes in service model instead of intermediate model
49+
}
50+
}

codegen/src/main/java/software/amazon/awssdk/codegen/customization/processors/DefaultCustomizationProcessor.java

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,7 @@ public static CodegenCustomizationProcessor getProcessorFor(
3232
new RenameShapesProcessor(config.getRenameShapes()),
3333
new ShapeModifiersProcessor(config.getShapeModifiers()),
3434
new ShapeSubstitutionsProcessor(config.getShapeSubstitutions()),
35+
new CustomSdkShapesProcessor(config.getCustomSdkShapes()),
3536
new OperationModifiersProcessor(config.getOperationModifiers()),
3637
new RemoveExceptionMessagePropertyProcessor(),
3738
new UseLegacyEventGenerationSchemeProcessor(),
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.model.config.customization;
17+
18+
import java.util.Collections;
19+
import java.util.Map;
20+
import software.amazon.awssdk.codegen.model.service.Shape;
21+
22+
public class CustomSdkShapes {
23+
private Map<String, Shape> shapes;
24+
25+
public Map<String, Shape> getShapes() {
26+
return shapes;
27+
}
28+
29+
public void setShapes(Map<String, Shape> shapes) {
30+
this.shapes = shapes != null ? Collections.unmodifiableMap(shapes) : Collections.emptyMap();
31+
}
32+
33+
public Shape getShape(String shapeName) {
34+
return shapes.get(shapeName);
35+
}
36+
}

codegen/src/main/java/software/amazon/awssdk/codegen/model/config/customization/CustomizationConfig.java

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -55,6 +55,7 @@ public class CustomizationConfig {
5555
*/
5656
private Map<String, OperationModifier> operationModifiers;
5757
private Map<String, ShapeSubstitution> shapeSubstitutions;
58+
private CustomSdkShapes customSdkShapes;
5859
private Map<String, ShapeModifier> shapeModifiers;
5960
/**
6061
* Sets the custom field name that identifies the type of modeled exception for JSON protocols.
@@ -253,6 +254,14 @@ public void setRenameShapes(Map<String, String> renameShapes) {
253254
this.renameShapes = renameShapes;
254255
}
255256

257+
public CustomSdkShapes getCustomSdkShapes() {
258+
return customSdkShapes;
259+
}
260+
261+
public void setCustomSdkShapes(CustomSdkShapes customSdkShapes) {
262+
this.customSdkShapes = customSdkShapes;
263+
}
264+
256265
public Map<String, ShapeSubstitution> getShapeSubstitutions() {
257266
return shapeSubstitutions;
258267
}

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

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -61,6 +61,8 @@ public class MemberModel extends DocumentationModel {
6161

6262
private boolean required;
6363

64+
private boolean synthetic;
65+
6466
private ListModel listModel;
6567

6668
private MapModel mapModel;
@@ -126,6 +128,14 @@ public MemberModel withName(String name) {
126128
return this;
127129
}
128130

131+
public boolean isSynthetic() {
132+
return synthetic;
133+
}
134+
135+
public void setSynthetic(boolean synthetic) {
136+
this.synthetic = synthetic;
137+
}
138+
129139
public String getC2jName() {
130140
return c2jName;
131141
}

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

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,8 @@ public class Shape {
3434

3535
private boolean flattened;
3636

37+
private boolean synthetic;
38+
3739
private boolean exception;
3840

3941
private boolean streaming;
@@ -155,6 +157,22 @@ public void setFlattened(boolean flattened) {
155157
this.flattened = flattened;
156158
}
157159

160+
/**
161+
* Returns flag that indicates whether this shape is a custom SDK shape. If true, this shape will be excluded from the static
162+
* SdkFields, preventing it from being marshalled.
163+
*/
164+
public boolean isSynthetic() {
165+
return synthetic;
166+
}
167+
168+
/**
169+
* Sets flag that indicates whether this shape is a custom SDK shape. If true, this shape will be excluded from the static
170+
* SdkFields, preventing it from being marshalled.
171+
*/
172+
public void setSynthetic(boolean synthetic) {
173+
this.synthetic = synthetic;
174+
}
175+
158176
public boolean isException() {
159177
return exception;
160178
}

codegen/src/main/java/software/amazon/awssdk/codegen/poet/model/ShapeModelSpec.java

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -97,6 +97,7 @@ public Iterable<FieldSpec> staticFields(Modifier... modifiers) {
9797
shapeModel.getNonStreamingMembers().stream()
9898
// Exceptions can be members of event stream shapes, need to filter those out of the models
9999
.filter(m -> m.getShape() == null || m.getShape().getShapeType() != ShapeType.Exception)
100+
.filter(m -> !m.isSynthetic())
100101
.forEach(m -> {
101102
FieldSpec field = typeProvider.asField(m, modifiers);
102103
ClassName sdkFieldType = ClassName.get(SdkField.class);
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,160 @@
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.customization.processors;
17+
18+
import static org.assertj.core.api.Assertions.assertThatNullPointerException;
19+
import static org.assertj.core.api.AssertionsForInterfaceTypes.assertThat;
20+
21+
import java.io.File;
22+
import java.io.IOException;
23+
import java.util.HashMap;
24+
import java.util.Map;
25+
import org.junit.jupiter.api.BeforeEach;
26+
import org.junit.jupiter.api.Test;
27+
import software.amazon.awssdk.codegen.C2jModels;
28+
import software.amazon.awssdk.codegen.IntermediateModelBuilder;
29+
import software.amazon.awssdk.codegen.model.config.customization.CustomSdkShapes;
30+
import software.amazon.awssdk.codegen.model.config.customization.CustomizationConfig;
31+
import software.amazon.awssdk.codegen.model.service.Member;
32+
import software.amazon.awssdk.codegen.model.service.ServiceModel;
33+
import software.amazon.awssdk.codegen.model.service.Shape;
34+
import software.amazon.awssdk.codegen.poet.model.AwsModelSpecTest;
35+
import software.amazon.awssdk.codegen.utils.ModelLoaderUtils;
36+
37+
public class CustomSdkShapesProcessorTest {
38+
39+
CustomizationConfig config;
40+
ServiceModel serviceModel;
41+
42+
@BeforeEach
43+
public void setUp() throws IOException {
44+
File serviceModelFile = new File(AwsModelSpecTest.class.getResource("service-2.json").getFile());
45+
File customizationConfigFile = new File(AwsModelSpecTest.class.getResource("customization.config").getFile());
46+
serviceModel = ModelLoaderUtils.loadModel(ServiceModel.class, serviceModelFile);
47+
config = ModelLoaderUtils.loadModel(CustomizationConfig.class, customizationConfigFile);
48+
}
49+
50+
@Test
51+
public void setCustomStringShape_isAddedToModel() {
52+
CustomSdkShapes customSdkShapes = config.getCustomSdkShapes();
53+
Map<String, Shape> shapes = new HashMap<>();
54+
shapes.putAll(customSdkShapes.getShapes());
55+
56+
Shape stringShape = new Shape();
57+
stringShape.setType("string");
58+
59+
String shapeName = "StringShape";
60+
shapes.put(shapeName, stringShape);
61+
customSdkShapes.setShapes(shapes);
62+
config.setCustomSdkShapes(customSdkShapes);
63+
64+
new IntermediateModelBuilder(C2jModels.builder()
65+
.serviceModel(serviceModel)
66+
.customizationConfig(config)
67+
.build())
68+
.build();
69+
70+
assertThat(serviceModel.getShapes()).containsKey(shapeName);
71+
assertThat(serviceModel.getShapes()).containsValue(stringShape);
72+
assertThat(serviceModel.getShape(shapeName).getType()).isEqualTo("string");
73+
}
74+
75+
@Test
76+
public void setCustomListShape_isAddedToModel() {
77+
CustomSdkShapes customSdkShapes = config.getCustomSdkShapes();
78+
Map<String, Shape> shapes = new HashMap<>();
79+
shapes.putAll(customSdkShapes.getShapes());
80+
81+
Shape listShape = new Shape();
82+
listShape.setType("list");
83+
84+
Member member = new Member();
85+
String memberName = "Event";
86+
member.setShape(memberName);
87+
listShape.setMember(member);
88+
89+
String shapeName = "ListShape";
90+
shapes.put(shapeName, listShape);
91+
customSdkShapes.setShapes(shapes);
92+
config.setCustomSdkShapes(customSdkShapes);
93+
94+
new IntermediateModelBuilder(C2jModels.builder()
95+
.serviceModel(serviceModel)
96+
.customizationConfig(config)
97+
.build())
98+
.build();
99+
100+
assertThat(serviceModel.getShapes()).containsKey(shapeName);
101+
assertThat(serviceModel.getShapes()).containsValue(listShape);
102+
assertThat(serviceModel.getShape(shapeName).getType()).isEqualTo("list");
103+
assertThat(serviceModel.getShape(shapeName).getListMember()).isEqualTo(member);
104+
assertThat(serviceModel.getShape(shapeName).getListMember().getShape()).isEqualTo("Event");
105+
}
106+
107+
@Test
108+
public void setCustomCustomizedShape_isAddedToModel() {
109+
CustomSdkShapes customSdkShapes = config.getCustomSdkShapes();
110+
Map<String, Shape> shapes = new HashMap<>();
111+
shapes.putAll(customSdkShapes.getShapes());
112+
113+
Shape stringShape = new Shape();
114+
stringShape.setType("string");
115+
116+
String shapeName = "StringShape";
117+
shapes.put(shapeName, stringShape);
118+
119+
Shape customizedShape = new Shape();
120+
customizedShape.setType(shapeName);
121+
String customizedShapeName = "CustomizedShape";
122+
shapes.put(customizedShapeName, customizedShape);
123+
124+
125+
customSdkShapes.setShapes(shapes);
126+
config.setCustomSdkShapes(customSdkShapes);
127+
128+
new IntermediateModelBuilder(C2jModels.builder()
129+
.serviceModel(serviceModel)
130+
.customizationConfig(config)
131+
.build())
132+
.build();
133+
134+
assertThat(serviceModel.getShapes()).containsKey(customizedShapeName);
135+
assertThat(serviceModel.getShapes()).containsValue(customizedShape);
136+
assertThat(serviceModel.getShape(customizedShapeName).getType()).isEqualTo(shapeName);
137+
}
138+
139+
@Test
140+
public void setCustomNullShape_throwsNullPointerException() {
141+
CustomSdkShapes customSdkShapes = config.getCustomSdkShapes();
142+
Map<String, Shape> shapes = new HashMap<>();
143+
shapes.putAll(customSdkShapes.getShapes());
144+
145+
Shape stringShape = new Shape();
146+
stringShape.setType(null);
147+
148+
String shapeName = "NullShape";
149+
shapes.put(shapeName, stringShape);
150+
customSdkShapes.setShapes(shapes);
151+
config.setCustomSdkShapes(customSdkShapes);
152+
153+
assertThatNullPointerException()
154+
.isThrownBy(() -> new IntermediateModelBuilder(C2jModels.builder()
155+
.serviceModel(serviceModel)
156+
.customizationConfig(config)
157+
.build()).
158+
build());
159+
}
160+
}

0 commit comments

Comments
 (0)