Skip to content

Commit 177e6ca

Browse files
committed
Add support for the retryable trait
1 parent 0d0d819 commit 177e6ca

File tree

15 files changed

+681
-8
lines changed

15 files changed

+681
-8
lines changed

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

Lines changed: 7 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -44,9 +44,10 @@ private Map<String, ShapeModel> constructExceptionShapes() {
4444
// Java shape models, to be constructed
4545
Map<String, ShapeModel> javaShapes = new HashMap<>();
4646

47-
for (Map.Entry<String, Shape> shape : getServiceModel().getShapes().entrySet()) {
48-
if (shape.getValue().isException()) {
49-
String errorShapeName = shape.getKey();
47+
for (Map.Entry<String, Shape> kvp : getServiceModel().getShapes().entrySet()) {
48+
if (kvp.getValue().isException()) {
49+
Shape shape = kvp.getValue();
50+
String errorShapeName = kvp.getKey();
5051
String javaClassName = getNamingStrategy().getExceptionName(errorShapeName);
5152

5253
ShapeModel exceptionShapeModel = generateShapeModel(javaClassName,
@@ -55,8 +56,10 @@ private Map<String, ShapeModel> constructExceptionShapes() {
5556
exceptionShapeModel.setType(ShapeType.Exception.getValue());
5657
exceptionShapeModel.setErrorCode(getErrorCode(errorShapeName));
5758
exceptionShapeModel.setHttpStatusCode(getHttpStatusCode(errorShapeName));
59+
exceptionShapeModel.withIsRetryable(shape.isRetryable());
60+
exceptionShapeModel.withIsThrottling(shape.isThrottling());
5861
if (exceptionShapeModel.getDocumentation() == null) {
59-
exceptionShapeModel.setDocumentation(shape.getValue().getDocumentation());
62+
exceptionShapeModel.setDocumentation(shape.getDocumentation());
6063
}
6164

6265
javaShapes.put(javaClassName, exceptionShapeModel);

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

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -87,6 +87,8 @@ protected final ShapeModel generateShapeModel(String javaClassName, String shape
8787
shapeModel.withXmlNamespace(shape.getXmlNamespace());
8888
shapeModel.withIsUnion(shape.isUnion());
8989
shapeModel.withIsFault(shape.isFault());
90+
shapeModel.withIsRetryable(shape.isRetryable());
91+
shapeModel.withIsThrottling(shape.isThrottling());
9092

9193
boolean hasHeaderMember = false;
9294
boolean hasStatusCodeMember = false;

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

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -75,6 +75,9 @@ public class ShapeModel extends DocumentationModel implements HasDeprecation {
7575

7676
private boolean union;
7777

78+
private boolean retryable;
79+
private boolean throttling;
80+
7881
public ShapeModel() {
7982
}
8083

@@ -648,4 +651,22 @@ public ShapeModel withIsFault(boolean fault) {
648651
this.fault = fault;
649652
return this;
650653
}
654+
655+
public boolean isRetryable() {
656+
return retryable;
657+
}
658+
659+
public ShapeModel withIsRetryable(boolean retryable) {
660+
this.retryable = retryable;
661+
return this;
662+
}
663+
664+
public boolean isThrottling() {
665+
return throttling;
666+
}
667+
668+
public ShapeModel withIsThrottling(boolean throttling) {
669+
this.throttling = throttling;
670+
return this;
671+
}
651672
}
Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
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.service;
17+
18+
public class RetryableTrait {
19+
20+
private Boolean throttling;
21+
22+
public void setThrottling(boolean throttling) {
23+
this.throttling = throttling;
24+
}
25+
26+
public Boolean getThrottling() {
27+
return throttling;
28+
}
29+
30+
public boolean isThrottling() {
31+
return Boolean.TRUE.equals(throttling);
32+
}
33+
}

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

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -78,6 +78,8 @@ public class Shape {
7878

7979
private boolean union;
8080

81+
private RetryableTrait retryable;
82+
8183
public boolean isFault() {
8284
return fault;
8385
}
@@ -345,4 +347,16 @@ public boolean isUnion() {
345347
public void setUnion(boolean union) {
346348
this.union = union;
347349
}
350+
351+
public void setRetryable(RetryableTrait retryable) {
352+
this.retryable = retryable;
353+
}
354+
355+
public boolean isRetryable() {
356+
return retryable != null;
357+
}
358+
359+
public boolean isThrottling() {
360+
return retryable != null && retryable.isThrottling();
361+
}
348362
}

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

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,7 @@
3434
import com.squareup.javapoet.WildcardTypeName;
3535
import java.io.Serializable;
3636
import java.util.ArrayList;
37+
import java.util.Arrays;
3738
import java.util.Collection;
3839
import java.util.Collections;
3940
import java.util.List;
@@ -437,6 +438,7 @@ private List<MethodSpec> modelClassMethods() {
437438
methodSpecs.add(builderMethod());
438439
methodSpecs.add(serializableBuilderClass());
439440
methodSpecs.addAll(memberGetters());
441+
methodSpecs.addAll(addRetryableOverrides());
440442
break;
441443
default:
442444
methodSpecs.addAll(addModifier(memberGetters(), FINAL));
@@ -689,6 +691,28 @@ private CodeBlock getterStatement(MemberModel model) {
689691
return CodeBlock.of("return $N;", modelVariable.getVariableName());
690692
}
691693

694+
private List<MethodSpec> addRetryableOverrides() {
695+
if (shapeModel.isRetryable()) {
696+
MethodSpec isRetryable = MethodSpec.methodBuilder("isRetryableException")
697+
.addAnnotation(Override.class)
698+
.addModifiers(PUBLIC)
699+
.returns(TypeName.BOOLEAN)
700+
.addStatement("return true")
701+
.build();
702+
if (shapeModel.isThrottling()) {
703+
MethodSpec isThrottling = MethodSpec.methodBuilder("isThrottlingException")
704+
.addAnnotation(Override.class)
705+
.addModifiers(PUBLIC)
706+
.returns(TypeName.BOOLEAN)
707+
.addStatement("return true")
708+
.build();
709+
return Arrays.asList(isRetryable, isThrottling);
710+
}
711+
return Arrays.asList(isRetryable);
712+
}
713+
return emptyList();
714+
}
715+
692716
private List<TypeSpec> nestedModelClassTypes() {
693717
List<TypeSpec> nestedClasses = new ArrayList<>();
694718
switch (shapeModel.getShapeType()) {
Lines changed: 61 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,61 @@
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.model;
17+
18+
import static org.hamcrest.MatcherAssert.assertThat;
19+
import static software.amazon.awssdk.codegen.poet.PoetMatchers.generatesTo;
20+
21+
import java.io.File;
22+
import java.io.IOException;
23+
import org.junit.jupiter.api.BeforeAll;
24+
import org.junit.jupiter.api.Test;
25+
import software.amazon.awssdk.codegen.C2jModels;
26+
import software.amazon.awssdk.codegen.IntermediateModelBuilder;
27+
import software.amazon.awssdk.codegen.model.config.customization.CustomizationConfig;
28+
import software.amazon.awssdk.codegen.model.intermediate.IntermediateModel;
29+
import software.amazon.awssdk.codegen.model.intermediate.ShapeType;
30+
import software.amazon.awssdk.codegen.model.service.ServiceModel;
31+
import software.amazon.awssdk.codegen.poet.ClassSpec;
32+
import software.amazon.awssdk.codegen.utils.ModelLoaderUtils;
33+
34+
public class RetryableExceptionClassSpecTest {
35+
private static IntermediateModel intermediateModel;
36+
37+
@BeforeAll
38+
public static void setUp() throws IOException {
39+
File serviceModelFile =
40+
new File(RetryableExceptionClassSpecTest.class.getResource("exceptions/service-2.json").getFile());
41+
File customizationConfigFile = new File(RetryableExceptionClassSpecTest.class.getResource("exceptions/customization.config")
42+
.getFile());
43+
intermediateModel = new IntermediateModelBuilder(
44+
C2jModels.builder()
45+
.serviceModel(ModelLoaderUtils.loadModel(ServiceModel.class, serviceModelFile))
46+
.customizationConfig(ModelLoaderUtils.loadModel(CustomizationConfig.class, customizationConfigFile))
47+
.build())
48+
.build();
49+
}
50+
51+
@Test
52+
public void serviceCodegen_withErrorsWithRetryableTrait_ShouldOverrideIsRetryableAndIsThrottling() {
53+
intermediateModel.getShapes().forEach((name, shape) -> {
54+
if (shape.getShapeType() == ShapeType.Exception) {
55+
ClassSpec spec = new AwsServiceModel(intermediateModel, shape);
56+
assertThat(spec, generatesTo( "exceptions/" + name.toLowerCase() + ".java"));
57+
}
58+
});
59+
}
60+
61+
}
Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
{}
2+
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,127 @@
1+
package software.amazon.awssdk.services.json.model;
2+
3+
import java.util.Arrays;
4+
import java.util.Collections;
5+
import java.util.List;
6+
import software.amazon.awssdk.annotations.Generated;
7+
import software.amazon.awssdk.awscore.exception.AwsErrorDetails;
8+
import software.amazon.awssdk.core.SdkField;
9+
import software.amazon.awssdk.core.SdkPojo;
10+
import software.amazon.awssdk.utils.builder.CopyableBuilder;
11+
import software.amazon.awssdk.utils.builder.ToCopyableBuilder;
12+
13+
/**
14+
* <p>
15+
* There was an internal server error.
16+
* </p>
17+
*/
18+
@Generated("software.amazon.awssdk:codegen")
19+
public final class JsonServiceInternalServerErrorException extends JsonException implements
20+
ToCopyableBuilder<JsonServiceInternalServerErrorException.Builder, JsonServiceInternalServerErrorException> {
21+
private static final List<SdkField<?>> SDK_FIELDS = Collections.unmodifiableList(Arrays.asList());
22+
23+
private static final long serialVersionUID = 1L;
24+
25+
private JsonServiceInternalServerErrorException(BuilderImpl builder) {
26+
super(builder);
27+
}
28+
29+
@Override
30+
public Builder toBuilder() {
31+
return new BuilderImpl(this);
32+
}
33+
34+
public static Builder builder() {
35+
return new BuilderImpl();
36+
}
37+
38+
public static Class<? extends Builder> serializableBuilderClass() {
39+
return BuilderImpl.class;
40+
}
41+
42+
@Override
43+
public boolean isRetryableException() {
44+
return true;
45+
}
46+
47+
@Override
48+
public final List<SdkField<?>> sdkFields() {
49+
return SDK_FIELDS;
50+
}
51+
52+
public interface Builder extends SdkPojo, CopyableBuilder<Builder, JsonServiceInternalServerErrorException>,
53+
JsonException.Builder {
54+
@Override
55+
Builder awsErrorDetails(AwsErrorDetails awsErrorDetails);
56+
57+
@Override
58+
Builder message(String message);
59+
60+
@Override
61+
Builder requestId(String requestId);
62+
63+
@Override
64+
Builder statusCode(int statusCode);
65+
66+
@Override
67+
Builder cause(Throwable cause);
68+
69+
@Override
70+
Builder writableStackTrace(Boolean writableStackTrace);
71+
}
72+
73+
static final class BuilderImpl extends JsonException.BuilderImpl implements Builder {
74+
private BuilderImpl() {
75+
}
76+
77+
private BuilderImpl(JsonServiceInternalServerErrorException model) {
78+
super(model);
79+
}
80+
81+
@Override
82+
public BuilderImpl awsErrorDetails(AwsErrorDetails awsErrorDetails) {
83+
this.awsErrorDetails = awsErrorDetails;
84+
return this;
85+
}
86+
87+
@Override
88+
public BuilderImpl message(String message) {
89+
this.message = message;
90+
return this;
91+
}
92+
93+
@Override
94+
public BuilderImpl requestId(String requestId) {
95+
this.requestId = requestId;
96+
return this;
97+
}
98+
99+
@Override
100+
public BuilderImpl statusCode(int statusCode) {
101+
this.statusCode = statusCode;
102+
return this;
103+
}
104+
105+
@Override
106+
public BuilderImpl cause(Throwable cause) {
107+
this.cause = cause;
108+
return this;
109+
}
110+
111+
@Override
112+
public BuilderImpl writableStackTrace(Boolean writableStackTrace) {
113+
this.writableStackTrace = writableStackTrace;
114+
return this;
115+
}
116+
117+
@Override
118+
public JsonServiceInternalServerErrorException build() {
119+
return new JsonServiceInternalServerErrorException(this);
120+
}
121+
122+
@Override
123+
public List<SdkField<?>> sdkFields() {
124+
return SDK_FIELDS;
125+
}
126+
}
127+
}

0 commit comments

Comments
 (0)