Skip to content

Commit f493979

Browse files
committed
Fail to build for services with unsupported payloads
1 parent f8c8a7e commit f493979

File tree

8 files changed

+799
-20
lines changed

8 files changed

+799
-20
lines changed

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

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,11 +19,13 @@
1919
import static software.amazon.awssdk.codegen.RemoveUnusedShapes.removeUnusedShapes;
2020

2121
import java.util.ArrayList;
22+
import java.util.Arrays;
2223
import java.util.Collections;
2324
import java.util.HashMap;
2425
import java.util.List;
2526
import java.util.Map;
2627
import java.util.TreeMap;
28+
import java.util.stream.Collectors;
2729
import org.slf4j.Logger;
2830
import org.slf4j.LoggerFactory;
2931
import software.amazon.awssdk.codegen.customization.CodegenCustomizationProcessor;
@@ -53,6 +55,8 @@
5355
*/
5456
public class IntermediateModelBuilder {
5557

58+
private static final List<String> NO_BODY_METHODS = Arrays.asList("GET", "HEAD", "DELETE");
59+
5660
private static final Logger log = LoggerFactory.getLogger(IntermediateModelBuilder.class);
5761
private final CustomizationConfig customConfig;
5862
private final ServiceModel service;
@@ -157,9 +161,28 @@ public IntermediateModel build() {
157161

158162
setSimpleMethods(trimmedModel);
159163

164+
validateOperations(trimmedModel);
165+
160166
return trimmedModel;
161167
}
162168

169+
/**
170+
* Validates that operations that use GET, DELETE or HEAD do not have an HTTP body.
171+
*/
172+
private void validateOperations(IntermediateModel model) {
173+
List<String> methods = model.getOperations()
174+
.values()
175+
.stream()
176+
.filter(e -> e.getInputShape().hasPayloadMembers())
177+
.filter(e -> NO_BODY_METHODS.contains(e.getInputShape().getMarshaller().getVerb()))
178+
.map(e -> e.getInputShape().getC2jName())
179+
.collect(Collectors.toList());
180+
181+
if (methods.size() > 0) {
182+
throw new RuntimeException("An HTTP body is not allowed on GET/DELETE/HEAD requests. Invalid operations: " + methods);
183+
}
184+
}
185+
163186
/**
164187
* Link the member to it's corresponding shape (if it exists).
165188
*
Lines changed: 49 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,49 @@
1+
/*
2+
* Copyright 2010-2019 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+
package software.amazon.awssdk.codegen;
16+
17+
import static org.junit.Assert.assertTrue;
18+
import static org.junit.Assert.fail;
19+
20+
import java.io.File;
21+
import org.junit.Test;
22+
import software.amazon.awssdk.codegen.model.config.customization.CustomizationConfig;
23+
import software.amazon.awssdk.codegen.model.service.ServiceModel;
24+
import software.amazon.awssdk.codegen.utils.ModelLoaderUtils;
25+
26+
public class IntermediateModelBuilderTest {
27+
28+
@Test(expected = RuntimeException.class)
29+
public void modelWithUnsupportedPayloadMethods_ThrowsException() {
30+
File serviceModel = new File(getClass().getResource("poet/client/c2j/unsupportedpayloads/service-2.json").getFile());
31+
File customizationModel = new File(getClass().getResource("poet/client/c2j/unsupportedpayloads/customization.config").getFile());
32+
33+
C2jModels models = C2jModels.builder()
34+
.serviceModel(ModelLoaderUtils.loadModel(ServiceModel.class, serviceModel))
35+
.customizationConfig(ModelLoaderUtils.loadModel(CustomizationConfig.class, customizationModel))
36+
.build();
37+
38+
try {
39+
new IntermediateModelBuilder(models).build();
40+
} catch (RuntimeException e) {
41+
assertTrue(e.getMessage().contains("GetBlacklistReportsRequest"));
42+
assertTrue(e.getMessage().contains("GetDedicatedIpsRequest"));
43+
throw e;
44+
}
45+
46+
fail("Expected RuntimeException");
47+
}
48+
49+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
{
2+
"authPolicyActions" : {
3+
"skip" : true
4+
}
5+
}

0 commit comments

Comments
 (0)