Skip to content

Commit ff912a7

Browse files
committed
Include shape name in REQUEST_URI_NOT_FOUND validation error message
1 parent 1ab875b commit ff912a7

File tree

3 files changed

+87
-1
lines changed

3 files changed

+87
-1
lines changed

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

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -367,7 +367,13 @@ private String findRequestUri(Shape parentShape, Map<String, Shape> allC2jShapes
367367

368368
return operation.map(o -> o.getHttp().getRequestUri())
369369
.orElseThrow(() -> {
370-
String detailMsg = "Could not find request URI for input shape for operation: " + operation;
370+
String shapeName = allC2jShapes.entrySet().stream()
371+
.filter(e -> e.getValue().equals(parentShape))
372+
.map(Map.Entry::getKey)
373+
.findFirst()
374+
.orElse("unknown");
375+
String detailMsg = "Could not find request URI for input shape '" + shapeName
376+
+ "'. No operation was found that references this shape as its input.";
371377
ValidationEntry entry =
372378
new ValidationEntry().withErrorId(ValidationErrorId.REQUEST_URI_NOT_FOUND)
373379
.withDetailMessage(detailMsg)

codegen/src/test/java/software/amazon/awssdk/codegen/CodeGeneratorTest.java

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -48,6 +48,7 @@
4848
import software.amazon.awssdk.codegen.poet.ClientTestModels;
4949
import software.amazon.awssdk.codegen.validation.ModelInvalidException;
5050
import software.amazon.awssdk.codegen.validation.ModelValidator;
51+
import software.amazon.awssdk.codegen.validation.ValidationEntry;
5152
import software.amazon.awssdk.codegen.validation.ValidationErrorId;
5253

5354
public class CodeGeneratorTest {
@@ -176,6 +177,23 @@ void execute_endpointsTestReferencesUnknownOperationMember_throwsValidationError
176177
});
177178
}
178179

180+
@Test
181+
void execute_uriLocationOnNonInputShape_throwsValidationErrorWithShapeName() throws IOException {
182+
C2jModels models = C2jModels.builder()
183+
.customizationConfig(CustomizationConfig.create())
184+
.serviceModel(getUriOnNonInputShapeServiceModel())
185+
.build();
186+
187+
assertThatThrownBy(() -> generateCodeFromC2jModels(models, outputDir, true, Collections.emptyList()))
188+
.isInstanceOf(ModelInvalidException.class)
189+
.matches(e -> {
190+
ModelInvalidException ex = (ModelInvalidException) e;
191+
ValidationEntry entry = ex.validationEntries().get(0);
192+
return entry.getErrorId() == ValidationErrorId.REQUEST_URI_NOT_FOUND
193+
&& entry.getDetailMessage().contains("No operation was found");
194+
});
195+
}
196+
179197
@Test
180198
void execute_operationHasNoRequestUri_throwsValidationError() throws IOException {
181199
C2jModels models = C2jModels.builder()
@@ -244,6 +262,11 @@ private ServiceModel getMissingRequestUriServiceModel() throws IOException {
244262
return Jackson.load(ServiceModel.class, json);
245263
}
246264

265+
private ServiceModel getUriOnNonInputShapeServiceModel() throws IOException {
266+
String json = resourceAsString("uri-on-non-input-shape-service.json");
267+
return Jackson.load(ServiceModel.class, json);
268+
}
269+
247270
private String resourceAsString(String name) throws IOException {
248271
ByteArrayOutputStream baos;
249272
try (InputStream resourceAsStream = getClass().getResourceAsStream(name)) {
Lines changed: 57 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,57 @@
1+
{
2+
"version": "2.0",
3+
"metadata": {
4+
"apiVersion": "2010-05-08",
5+
"endpointPrefix": "json-service-endpoint",
6+
"globalEndpoint": "json-service.amazonaws.com",
7+
"protocol": "rest-json",
8+
"serviceAbbreviation": "Rest Json Service",
9+
"serviceFullName": "Some Service That Uses Rest-Json Protocol",
10+
"serviceId": "Rest Json Service",
11+
"signingName": "json-service",
12+
"signatureVersion": "v4",
13+
"uid": "json-service-2010-05-08",
14+
"xmlNamespace": "https://json-service.amazonaws.com/doc/2010-05-08/"
15+
},
16+
"operations": {
17+
"SomeOperation": {
18+
"name": "SomeOperation",
19+
"http": {
20+
"method": "POST",
21+
"requestUri": "/things/{thingId}"
22+
},
23+
"input": {
24+
"shape": "SomeOperationRequest"
25+
}
26+
}
27+
},
28+
"shapes": {
29+
"SomeOperationRequest": {
30+
"type": "structure",
31+
"members": {
32+
"thingId": {
33+
"shape": "String",
34+
"location": "uri",
35+
"locationName": "thingId"
36+
},
37+
"options": {
38+
"shape": "NestedOptions"
39+
}
40+
}
41+
},
42+
"NestedOptions": {
43+
"type": "structure",
44+
"members": {
45+
"pageSize": {
46+
"shape": "String",
47+
"location": "uri",
48+
"locationName": "pageSize"
49+
}
50+
}
51+
},
52+
"String": {
53+
"type": "string"
54+
}
55+
},
56+
"documentation": "A service with a uri-bound member on a non-input shape"
57+
}

0 commit comments

Comments
 (0)