Skip to content

Commit 795acc6

Browse files
committed
Corrected logic and added test for locationName
1 parent 114c432 commit 795acc6

File tree

6 files changed

+66
-15
lines changed

6 files changed

+66
-15
lines changed

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

Lines changed: 10 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -311,17 +311,23 @@ private ParameterHttpMapping generateParameterHttpMapping(Shape parentShape,
311311

312312
ParameterHttpMapping mapping = new ParameterHttpMapping();
313313

314-
// Per the Smithy spec, HTTP binding traits are only honored on specific shape types:
314+
// Per the Smithy spec, HTTP binding traits are only honored on specific shape types.
315+
// When a trait is ignored, its locationName is also ignored so the member name is used as the wire name.
315316
// https://smithy.io/2.0/spec/http-bindings.html
316317
Location location = resolveLocation(parentShape, member, allC2jShapes);
318+
boolean locationIgnored = member.getLocation() != null && location == null;
317319

318320
Shape memberShape = allC2jShapes.get(member.getShape());
321+
String marshallLocationName = locationIgnored
322+
? memberName : deriveMarshallerLocationName(memberShape, memberName, member, protocol);
323+
String unmarshallLocationName = locationIgnored
324+
? memberName : deriveUnmarshallerLocationName(memberShape, memberName, member);
325+
319326
mapping.withLocation(location)
320327
.withPayload(member.isPayload()).withStreaming(member.isStreaming())
321328
.withFlattened(isFlattened(member, memberShape))
322-
.withUnmarshallLocationName(deriveUnmarshallerLocationName(memberShape, memberName, member))
323-
.withMarshallLocationName(
324-
deriveMarshallerLocationName(memberShape, memberName, member, protocol))
329+
.withUnmarshallLocationName(unmarshallLocationName)
330+
.withMarshallLocationName(marshallLocationName)
325331
.withIsGreedy(isGreedy(parentShape, allC2jShapes, mapping));
326332

327333
return mapping;

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

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -103,4 +103,10 @@ void generateShapeModel_locationOnDirectInputShape_isPreserved() {
103103
assertThat(inputShape.findMemberModelByC2jName("StringHeaderMember").getHttp().getLocation()).isEqualTo(Location.HEADER);
104104
}
105105

106+
@Test
107+
void generateShapeModel_locationNameOnNestedShape_usesMemberNameForMarshalling() {
108+
ShapeModel inputShape = intermediateModel.getShapes().get("NestedQueryParameterOperation");
109+
assertThat(inputShape.findMemberModelByC2jName("NestedHeaderMember").getHttp().getMarshallLocationName()).isEqualTo("NestedHeaderMember");
110+
}
111+
106112
}

codegen/src/test/resources/software/amazon/awssdk/codegen/expected-nested-options.java

Lines changed: 6 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -48,19 +48,18 @@ public final class NestedOptions implements SdkPojo, Serializable, ToCopyableBui
4848

4949
private static final SdkField<String> HEADER_PARAM_FIELD = SdkField.<String> builder(MarshallingType.STRING)
5050
.memberName("headerParam").getter(getter(NestedOptions::headerParam)).setter(setter(Builder::headerParam))
51-
.traits(LocationTrait.builder().location(MarshallLocation.PAYLOAD).locationName("x-amz-nested-header").build())
52-
.build();
51+
.traits(LocationTrait.builder().location(MarshallLocation.PAYLOAD).locationName("headerParam").build()).build();
5352

5453
private static final SdkField<String> QUERY_PARAM_FIELD = SdkField.<String> builder(MarshallingType.STRING)
5554
.memberName("queryParam").getter(getter(NestedOptions::queryParam)).setter(setter(Builder::queryParam))
56-
.traits(LocationTrait.builder().location(MarshallLocation.PAYLOAD).locationName("nestedQuery").build()).build();
55+
.traits(LocationTrait.builder().location(MarshallLocation.PAYLOAD).locationName("queryParam").build()).build();
5756

5857
private static final SdkField<Map<String, String>> PREFIX_HEADERS_FIELD = SdkField
5958
.<Map<String, String>> builder(MarshallingType.MAP)
6059
.memberName("prefixHeaders")
6160
.getter(getter(NestedOptions::prefixHeaders))
6261
.setter(setter(Builder::prefixHeaders))
63-
.traits(LocationTrait.builder().location(MarshallLocation.PAYLOAD).locationName("x-amz-prefix-").build(),
62+
.traits(LocationTrait.builder().location(MarshallLocation.PAYLOAD).locationName("prefixHeaders").build(),
6463
MapTrait.builder()
6564
.keyLocationName("key")
6665
.valueLocationName("value")
@@ -229,9 +228,9 @@ public final Map<String, SdkField<?>> sdkFieldNameToField() {
229228
private static Map<String, SdkField<?>> memberNameToFieldInitializer() {
230229
Map<String, SdkField<?>> map = new HashMap<>();
231230
map.put("pageSize", PAGE_SIZE_FIELD);
232-
map.put("x-amz-nested-header", HEADER_PARAM_FIELD);
233-
map.put("nestedQuery", QUERY_PARAM_FIELD);
234-
map.put("x-amz-prefix-", PREFIX_HEADERS_FIELD);
231+
map.put("headerParam", HEADER_PARAM_FIELD);
232+
map.put("queryParam", QUERY_PARAM_FIELD);
233+
map.put("prefixHeaders", PREFIX_HEADERS_FIELD);
235234
return Collections.unmodifiableMap(map);
236235
}
237236

codegen/src/test/resources/software/amazon/awssdk/codegen/poet/model/nestedqueryparameteroperation.java

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -51,7 +51,7 @@ public final class NestedQueryParameterOperation implements SdkPojo, Serializabl
5151
.setter(setter(Builder::nestedHeaderMember))
5252
.traits(LocationTrait.builder()
5353
.location(MarshallLocation.PAYLOAD)
54-
.locationName("x-amz-nested-header")
54+
.locationName("NestedHeaderMember")
5555
.build()).build();
5656

5757
private static final SdkField<Integer> NESTED_STATUS_CODE_FIELD = SdkField.<Integer>builder(MarshallingType.INTEGER)
@@ -191,7 +191,7 @@ private static Map<String, SdkField<?>> memberNameToFieldInitializer() {
191191
Map<String, SdkField<?>> map = new HashMap<>();
192192
map.put("QueryParamOne", QUERY_PARAM_ONE_FIELD);
193193
map.put("QueryParamTwo", QUERY_PARAM_TWO_FIELD);
194-
map.put("x-amz-nested-header", NESTED_HEADER_MEMBER_FIELD);
194+
map.put("NestedHeaderMember", NESTED_HEADER_MEMBER_FIELD);
195195
map.put("NestedStatusCode", NESTED_STATUS_CODE_FIELD);
196196
return Collections.unmodifiableMap(map);
197197
}

test/protocol-tests/src/main/resources/codegen-resources/restjson/service-2.json

Lines changed: 24 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -262,7 +262,8 @@
262262
"method":"POST",
263263
"requestUri":"/2016-03-11/nestedLocationOperation"
264264
},
265-
"input":{"shape":"NestedLocationOperationInput"}
265+
"input":{"shape":"NestedLocationOperationInput"},
266+
"output":{"shape":"NestedLocationOperationOutput"}
266267
}
267268
},
268269
"shapes":{
@@ -812,6 +813,28 @@
812813
"StringMember":{"shape":"String"}
813814
}
814815
},
816+
"NestedLocationOperationOutput":{
817+
"type":"structure",
818+
"members":{
819+
"TopLevelHeader":{
820+
"shape":"String",
821+
"location":"header",
822+
"locationName":"x-amz-top-level"
823+
},
824+
"NestedResult":{"shape":"NestedResponseData"}
825+
}
826+
},
827+
"NestedResponseData":{
828+
"type":"structure",
829+
"members":{
830+
"NestedHeader":{
831+
"shape":"String",
832+
"location":"header",
833+
"locationName":"x-amz-should-be-ignored"
834+
},
835+
"Value":{"shape":"String"}
836+
}
837+
},
815838
"StatusCodeInOutputStructure":{
816839
"type":"structure",
817840
"members":{

test/protocol-tests/src/test/java/software/amazon/awssdk/protocol/tests/NestedLocationSerializationTest.java

Lines changed: 18 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@
2323
import static com.github.tomakehurst.wiremock.client.WireMock.postRequestedFor;
2424
import static com.github.tomakehurst.wiremock.client.WireMock.stubFor;
2525
import static com.github.tomakehurst.wiremock.client.WireMock.verify;
26+
import static org.assertj.core.api.Assertions.assertThat;
2627

2728
import com.github.tomakehurst.wiremock.junit.WireMockRule;
2829
import java.net.URI;
@@ -34,6 +35,7 @@
3435
import software.amazon.awssdk.regions.Region;
3536
import software.amazon.awssdk.services.protocolrestjson.ProtocolRestJsonClient;
3637
import software.amazon.awssdk.services.protocolrestjson.model.NestedLocationOperationRequest;
38+
import software.amazon.awssdk.services.protocolrestjson.model.NestedLocationOperationResponse;
3739
import software.amazon.awssdk.services.protocolrestjson.model.NestedShapeWithLocations;
3840

3941
/**
@@ -71,6 +73,21 @@ public void nestedMemberWithLocation_serializedToBodyNotQueryParam() {
7173
verify(postRequestedFor(anyUrl()).withQueryParam("topLevel", equalTo("topValue")));
7274

7375
verify(postRequestedFor(anyUrl()).withRequestBody(
74-
equalToJson("{\"Nested\":{\"shouldBeIgnored\":\"nestedValue\",\"StringMember\":\"hello\"}}")));
76+
equalToJson("{\"Nested\":{\"NestedQueryParam\":\"nestedValue\",\"StringMember\":\"hello\"}}")));
77+
}
78+
79+
@Test
80+
public void nestedMemberWithLocation_deserializedFromBodyNotHeader() {
81+
stubFor(post(anyUrl()).willReturn(aResponse()
82+
.withStatus(200)
83+
.withHeader("x-amz-top-level", "headerValue")
84+
.withBody("{\"NestedResult\":{\"NestedHeader\":\"from-body\",\"Value\":\"hello\"}}")));
85+
86+
NestedLocationOperationResponse response = client.nestedLocationOperation(
87+
NestedLocationOperationRequest.builder().build());
88+
89+
assertThat(response.topLevelHeader()).isEqualTo("headerValue");
90+
assertThat(response.nestedResult().nestedHeader()).isEqualTo("from-body");
91+
assertThat(response.nestedResult().value()).isEqualTo("hello");
7592
}
7693
}

0 commit comments

Comments
 (0)