Skip to content

Commit

Permalink
Fix codegen for implicit event payloads with a single enum field (#3056)
Browse files Browse the repository at this point in the history
* update codegen for enums
  • Loading branch information
DmitriyMusatkin authored Jul 26, 2024
1 parent 29a7ec6 commit f77e736
Show file tree
Hide file tree
Showing 3 changed files with 70 additions and 8 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ namespace Model
{

/**
* <p>The streaming input for the <code>Chat</code> API.</p><p><h3>See Also:</h3>
* <p>The streaming input for the <code>Chat</code> API.</p><p><h3>See Also:</h3>
* <a
* href="http://docs.aws.amazon.com/goto/WebAPI/qbusiness-2023-11-27/ChatInputStream">AWS
* API Reference</a></p>
Expand Down Expand Up @@ -85,7 +85,8 @@ namespace Model
Aws::Utils::Event::Message msg;
msg.InsertEventHeader(":message-type", Aws::String("event"));
msg.InsertEventHeader(":event-type", Aws::String("AuthChallengeResponseEvent"));
AWS_UNREFERENCED_PARAM(value);
msg.InsertEventHeader(":content-type", Aws::String("application/json"));
msg.WriteEventPayload(value.Jsonize().View().WriteCompact());
WriteEvent(msg);
return *this;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -305,9 +305,32 @@ header insertion there. So strip this out of the model (affects S3's PutObjectR
} else if (shape.hasEventPayloadMembers() || shape.getMembers().size() == 1) {
if (shape.getMembers().size() == 1) {
shape.getMembers().entrySet().stream().forEach(memberEntry -> {
memberEntry.getValue().setEventPayload(true);
shape.setEventPayloadMemberName(memberEntry.getKey());
shape.setEventPayloadType(memberEntry.getValue().getShape().getType());
/**
* Note: this is complicated and potentially not completely correct.
* So touch at your own risk until we have protocol tests supported.
* In summary:
* - we need to determine how to serialize events in eventstream
* - to specify payload there is an eventpayload trait
* - but what happens if that trait is not specified
* - if there is one field and its a string, blob or struct then we assume that field is event payload
* (note: this might not be completely correct, spec is vague on that and other sdks do implicit struct around string and blob)
* - if that one field is of any other type then treat parent shape as eventpayload
* - if there is more than one field then parent shape is the payload
*/
Shape memberShape = memberEntry.getValue().getShape();
if (memberShape.isString() ||
memberShape.isBlob() ||
memberShape.isStructure()) {
memberEntry.getValue().setEventPayload(true);
shape.setEventPayloadMemberName(memberEntry.getKey());
shape.setEventPayloadType(memberShape.getType());
} else {
if (!shape.getType().equals("structure")) {
throw new RuntimeException("Event shape should always has \"structure\" type if single member cannot be event payload.");
}
shape.setEventPayloadType(shape.getType());
}

});
} else {
throw new RuntimeException("Event shape used in Event Stream should only has one member if it has event payload member.");
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,8 +13,10 @@
import java.util.HashMap;
import java.util.LinkedList;
import java.util.Map;
import com.google.common.collect.ImmutableList;

import static org.junit.Assert.assertTrue;
import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertEquals;

public class C2jModelToGeneratorModelTransformerTest {
Expand Down Expand Up @@ -342,7 +344,8 @@ public void testOperationConversion() {
// "EventStreamShape":{
// "type":"structure",
// "members":{
// "EventShape":{"shape":"EventShape"}
// "EventShape":{"shape":"EventShape"},
// "EventEnumShape":{"shape":"EventEnumShape"}
// },
// "eventstream":true
// },
Expand All @@ -353,6 +356,17 @@ public void testOperationConversion() {
// },
// "event":true
// },
// "EventEnumShape":{
// "type":"structure",
// "members":{
// "BlobShape":{"shape":"BlobShape"}
// },
// "event":true
// },
// "EnumShape":{
// "type":"string",
// "enum":[VALUE]
// }
// "BlobShape":{
// "type":"blob"
// }
Expand Down Expand Up @@ -390,14 +404,35 @@ public void testEventStreamShapeConversion() {
eventStreamShape.setMembers(new HashMap<>());
eventStreamShape.getMembers().put("EventShape", eventShapeMember);

C2jShape eventEnumShape = new C2jShape();
eventEnumShape.setType("structure");
eventEnumShape.setEvent(true);
c2jShapeMap.put("EventEnumShape", eventEnumShape);

C2jShape enumShape = new C2jShape();
enumShape.setType("string");
enumShape.setEnums(ImmutableList.of("VALUE"));
c2jShapeMap.put("EnumShape", enumShape);

C2jShapeMember enumShapeMember = new C2jShapeMember();
enumShapeMember.setShape("EnumShape");

eventEnumShape.setMembers(new HashMap<>());
eventEnumShape.getMembers().put("EnumShape", enumShapeMember);

C2jShapeMember eventEnumShapeMember = new C2jShapeMember();
eventEnumShapeMember.setShape("EventEnumShape");

eventStreamShape.getMembers().put("EvenEnumShape", eventEnumShapeMember);

c2jServiceModel.setShapes(c2jShapeMap);

C2jModelToGeneratorModelTransformer c2jModelToGeneratorModelTransformer = new C2jModelToGeneratorModelTransformer(c2jServiceModel, false);
c2jModelToGeneratorModelTransformer.convertShapes();
c2jModelToGeneratorModelTransformer.postProcessShapes();

Map<String, Shape> shapes = c2jModelToGeneratorModelTransformer.shapes;
assertEquals(3, shapes.size());
assertEquals(5, shapes.size());
assertEquals("EventStreamShape", shapes.get("EventStreamShape").getName());
assertTrue(shapes.get("EventStreamShape").isEventStream());
assertEquals("EventShape", shapes.get("EventShape").getName());
Expand All @@ -406,10 +441,13 @@ public void testEventStreamShapeConversion() {
assertEquals("BlobShape", shapes.get("EventShape").getEventPayloadMemberName());
assertEquals("BlobShape", shapes.get("BlobShape").getName());
assertEquals("blob", shapes.get("BlobShape").getType());
assertEquals(1, shapes.get("EventStreamShape").getMembers().size());
assertEquals(2, shapes.get("EventStreamShape").getMembers().size());
assertEquals("EventShape", shapes.get("EventStreamShape").getMembers().get("EventShape").getShape().getName());
assertEquals(1, shapes.get("EventShape").getMembers().size());
assertEquals("BlobShape", shapes.get("EventShape").getMembers().get("BlobShape").getShape().getName());
assertTrue(shapes.get("EventShape").getMembers().get("BlobShape").isEventPayload());

assertFalse(shapes.get("EventEnumShape").getMembers().get("EnumShape").isEventPayload());
assertEquals("structure", shapes.get("EventEnumShape").getEventPayloadType());
}
}

0 comments on commit f77e736

Please sign in to comment.