Skip to content

Commit 622089b

Browse files
committed
Fix greedy label param names in OpenAPI
Services like API Gateway that use "greedy" labels require that bath the segment and the corresponding parameter name contain a "+". We previously included the "+" in the URI label but not in the parameter name.
1 parent a1bb42e commit 622089b

File tree

4 files changed

+105
-1
lines changed

4 files changed

+105
-1
lines changed

smithy-openapi/src/main/java/software/amazon/smithy/openapi/fromsmithy/protocols/AbstractRestProtocol.java

+18
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,7 @@
2929
import software.amazon.smithy.model.knowledge.HttpBinding;
3030
import software.amazon.smithy.model.knowledge.HttpBindingIndex;
3131
import software.amazon.smithy.model.knowledge.OperationIndex;
32+
import software.amazon.smithy.model.pattern.SmithyPattern;
3233
import software.amazon.smithy.model.shapes.CollectionShape;
3334
import software.amazon.smithy.model.shapes.MemberShape;
3435
import software.amazon.smithy.model.shapes.OperationShape;
@@ -38,6 +39,7 @@
3839
import software.amazon.smithy.model.traits.HttpTrait;
3940
import software.amazon.smithy.model.traits.TimestampFormatTrait;
4041
import software.amazon.smithy.model.traits.Trait;
42+
import software.amazon.smithy.openapi.OpenApiException;
4143
import software.amazon.smithy.openapi.fromsmithy.Context;
4244
import software.amazon.smithy.openapi.fromsmithy.OpenApiProtocol;
4345
import software.amazon.smithy.openapi.model.MediaTypeObject;
@@ -120,10 +122,26 @@ public Optional<Operation> createOperation(Context<T> context, OperationShape op
120122
private List<ParameterObject> createPathParameters(Context<T> context, OperationShape operation) {
121123
List<ParameterObject> result = new ArrayList<>();
122124
HttpBindingIndex bindingIndex = HttpBindingIndex.of(context.getModel());
125+
HttpTrait httpTrait = operation.expectTrait(HttpTrait.class);
123126

124127
for (HttpBinding binding : bindingIndex.getRequestBindings(operation, HttpBinding.Location.LABEL)) {
125128
Schema schema = createPathParameterSchema(context, binding);
129+
String memberName = binding.getMemberName();
130+
131+
SmithyPattern.Segment label = httpTrait.getUri()
132+
.getLabel(memberName)
133+
.orElseThrow(() -> new OpenApiException(String.format(
134+
"Unable to find URI label on %s for %s: %s",
135+
operation.getId(),
136+
binding.getMemberName(),
137+
httpTrait.getUri())));
138+
139+
// Greedy labels in OpenAPI need to include the label in the generated parameter.
140+
// For example, given "/{foo+}", the parameter name must be "foo+".
141+
String name = label.isGreedyLabel() ? label.getContent() + "+" : label.getContent();
142+
126143
result.add(ModelUtils.createParameterMember(context, binding.getMember())
144+
.name(name)
127145
.in("path")
128146
.schema(schema)
129147
.build());

smithy-openapi/src/test/java/software/amazon/smithy/openapi/fromsmithy/protocols/AwsRestJson1ProtocolTest.java

+2-1
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,8 @@ public class AwsRestJson1ProtocolTest {
2727
"adds-header-mediatype-format.json",
2828
"supports-payloads.json",
2929
"aws-rest-json-uses-jsonname.json",
30-
"synthesizes-contents.json"
30+
"synthesizes-contents.json",
31+
"greedy-labels.json"
3132
})
3233

3334
public void testProtocolResult(String smithy) {
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,48 @@
1+
{
2+
"smithy": "1.0",
3+
"shapes": {
4+
"smithy.example#Service": {
5+
"type": "service",
6+
"version": "2006-03-01",
7+
"operations": [
8+
{
9+
"target": "smithy.example#Operation"
10+
}
11+
],
12+
"traits": {
13+
"aws.protocols#restJson1": {}
14+
}
15+
},
16+
"smithy.example#Operation": {
17+
"type": "operation",
18+
"input": {
19+
"target": "smithy.example#OperationInput"
20+
},
21+
"traits": {
22+
"smithy.api#http": {
23+
"uri": "/{foo}/{baz+}",
24+
"method": "POST"
25+
}
26+
}
27+
},
28+
"smithy.example#OperationInput": {
29+
"type": "structure",
30+
"members": {
31+
"foo": {
32+
"target": "smithy.api#String",
33+
"traits": {
34+
"smithy.api#required": {},
35+
"smithy.api#httpLabel": {}
36+
}
37+
},
38+
"baz": {
39+
"target": "smithy.api#String",
40+
"traits": {
41+
"smithy.api#required": {},
42+
"smithy.api#httpLabel": {}
43+
}
44+
}
45+
}
46+
}
47+
}
48+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,37 @@
1+
{
2+
"openapi": "3.0.2",
3+
"info": {
4+
"title": "Service",
5+
"version": "2006-03-01"
6+
},
7+
"paths": {
8+
"/{foo}/{baz+}": {
9+
"post": {
10+
"operationId": "Operation",
11+
"parameters": [
12+
{
13+
"name": "foo",
14+
"in": "path",
15+
"schema": {
16+
"type": "string"
17+
},
18+
"required": true
19+
},
20+
{
21+
"name": "baz+",
22+
"in": "path",
23+
"schema": {
24+
"type": "string"
25+
},
26+
"required": true
27+
}
28+
],
29+
"responses": {
30+
"200": {
31+
"description": "Operation response"
32+
}
33+
}
34+
}
35+
}
36+
}
37+
}

0 commit comments

Comments
 (0)