Skip to content

Commit 6553441

Browse files
committed
Event transformation based on type
Fixes event marshalling and unmarshalling: - Fix unmarshalling by mapping event type to the correct builder static constructor on the eventstream interface. - Fix marshalling by retrieving the value for the :event-type header from the event using getSdkEventType()
1 parent 308e493 commit 6553441

File tree

10 files changed

+46
-45
lines changed

10 files changed

+46
-45
lines changed

codegen/src/main/java/software/amazon/awssdk/codegen/poet/client/specs/JsonProtocolSpec.java

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -41,6 +41,7 @@
4141
import software.amazon.awssdk.codegen.poet.PoetExtensions;
4242
import software.amazon.awssdk.codegen.poet.client.traits.HttpChecksumRequiredTrait;
4343
import software.amazon.awssdk.codegen.poet.eventstream.EventStreamUtils;
44+
import software.amazon.awssdk.codegen.poet.model.EventStreamSpecHelper;
4445
import software.amazon.awssdk.core.SdkPojoBuilder;
4546
import software.amazon.awssdk.core.SdkResponse;
4647
import software.amazon.awssdk.core.async.AsyncRequestBody;
@@ -419,9 +420,14 @@ private void responseHandlersForEventStreaming(OperationModel opModel, TypeName
419420
protocolFactory,
420421
JsonOperationMetadata.class,
421422
ClassName.get(EventStreamTaggedUnionPojoSupplier.class));
423+
424+
EventStreamSpecHelper eventStreamSpecHelper = new EventStreamSpecHelper(eventStream, model);
422425
EventStreamUtils.getEventMembers(eventStream)
423-
.forEach(m -> builder.add(".putSdkPojoSupplier(\"$L\", $T::builder)\n",
424-
m.getC2jName(), poetExtensions.getModelClass(m.getShape().getC2jName())));
426+
.forEach(m -> {
427+
String builderMethod = eventStreamSpecHelper.eventBuilderMethodName(m);
428+
builder.add(".putSdkPojoSupplier($S, $T::$N)",
429+
m.getC2jName(), eventStreamBaseClass, builderMethod);
430+
});
425431
builder.add(".defaultSdkPojoSupplier(() -> new $T($T.UNKNOWN))\n"
426432
+ ".build());\n", SdkPojoBuilder.class, eventStreamBaseClass);
427433
}

codegen/src/main/java/software/amazon/awssdk/codegen/poet/model/AwsServiceModel.java

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -699,9 +699,7 @@ private MethodSpec eventBuilderMethod(MemberModel event) {
699699
returnType = baseClass.nestedClass("Builder");
700700
}
701701

702-
String eventClass = intermediateModel.getNamingStrategy().getShapeClassName(event.getName());
703-
String methodName = String.format("%sBuilder", StringUtils.uncapitalize(eventClass));
704-
702+
String methodName = specHelper.eventBuilderMethodName(event);
705703
return MethodSpec.methodBuilder(methodName)
706704
.addModifiers(PUBLIC, Modifier.STATIC)
707705
.returns(returnType)

codegen/src/main/java/software/amazon/awssdk/codegen/poet/model/EventStreamSpecHelper.java

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,7 @@
2929
import software.amazon.awssdk.codegen.naming.NamingStrategy;
3030
import software.amazon.awssdk.codegen.poet.PoetExtensions;
3131
import software.amazon.awssdk.codegen.poet.eventstream.EventTypeEnumSpec;
32+
import software.amazon.awssdk.utils.StringUtils;
3233
import software.amazon.awssdk.utils.internal.CodegenNamingUtils;
3334

3435
public final class EventStreamSpecHelper {
@@ -91,4 +92,8 @@ public String eventTypeEnumValue(MemberModel eventModel) {
9192
NamingStrategy namingStrategy = intermediateModel.getNamingStrategy();
9293
return namingStrategy.getEnumValueName(eventModel.getName());
9394
}
95+
96+
public String eventBuilderMethodName(MemberModel eventModel) {
97+
return String.format("%sBuilder", StringUtils.uncapitalize(eventModel.getName()));
98+
}
9499
}

codegen/src/main/java/software/amazon/awssdk/codegen/poet/transform/protocols/EventStreamJsonMarshallerSpec.java

Lines changed: 2 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,6 @@
2222
import software.amazon.awssdk.codegen.model.intermediate.IntermediateModel;
2323
import software.amazon.awssdk.codegen.model.intermediate.MemberModel;
2424
import software.amazon.awssdk.codegen.model.intermediate.ShapeModel;
25-
import software.amazon.awssdk.codegen.poet.eventstream.EventStreamUtils;
2625
import software.amazon.awssdk.http.SdkHttpFullRequest;
2726
import software.amazon.awssdk.http.SdkHttpMethod;
2827
import software.amazon.awssdk.protocols.core.OperationInfo;
@@ -35,11 +34,8 @@ public final class EventStreamJsonMarshallerSpec extends JsonMarshallerSpec {
3534

3635
private static final String JSON_CONTENT_TYPE = "application/json";
3736

38-
private final IntermediateModel intermediateModel;
39-
4037
public EventStreamJsonMarshallerSpec(IntermediateModel model, ShapeModel shapeModel) {
4138
super(shapeModel);
42-
this.intermediateModel = model;
4339
}
4440

4541
@Override
@@ -50,8 +46,8 @@ public CodeBlock marshalCodeBlock(ClassName requestClassName) {
5046
.addStatement("$T<$T> protocolMarshaller = protocolFactory.createProtocolMarshaller(SDK_OPERATION_BINDING)",
5147
ProtocolMarshaller.class, SdkHttpFullRequest.class)
5248
.add("return protocolMarshaller.marshall($L).toBuilder()", variableName)
53-
.add(".putHeader(\":message-type\", \"event\")")
54-
.add(".putHeader(\":event-type\", \"$L\")", getMemberNameFromEventStream());
49+
.add(".putHeader($S, $S)", ":message-type", "event")
50+
.add(".putHeader($S, $N.sdkEventType().toString())", ":event-type", variableName);
5551

5652
// Add :content-type header only if payload is present
5753
if (!shapeModel.hasNoEventPayload()) {
@@ -83,18 +79,6 @@ protected FieldSpec operationInfoField() {
8379
.build();
8480
}
8581

86-
private String getMemberNameFromEventStream() {
87-
ShapeModel eventStream = EventStreamUtils.getBaseEventStreamShape(intermediateModel, shapeModel)
88-
.orElseThrow(() -> new IllegalStateException("Could not find associated event stream spec for "
89-
+ shapeModel.getC2jName()));
90-
return eventStream.getMembers().stream()
91-
.filter(memberModel -> memberModel.getShape().equals(shapeModel))
92-
.findAny()
93-
.map(MemberModel::getC2jName)
94-
.orElseThrow(() -> new IllegalStateException(
95-
String.format("Unable to find %s from its parent event stream", shapeModel.getC2jName())));
96-
}
97-
9882
private String determinePayloadContentType() {
9983
MemberModel explicitEventPayload = shapeModel.getExplicitEventPayloadMember();
10084
if (explicitEventPayload != null) {

codegen/src/test/resources/software/amazon/awssdk/codegen/poet/client/test-async-client-class.java

Lines changed: 6 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -57,7 +57,6 @@
5757
import software.amazon.awssdk.services.json.model.APostOperationResponse;
5858
import software.amazon.awssdk.services.json.model.APostOperationWithOutputRequest;
5959
import software.amazon.awssdk.services.json.model.APostOperationWithOutputResponse;
60-
import software.amazon.awssdk.services.json.model.EventOne;
6160
import software.amazon.awssdk.services.json.model.EventStream;
6261
import software.amazon.awssdk.services.json.model.EventStreamOperationRequest;
6362
import software.amazon.awssdk.services.json.model.EventStreamOperationResponse;
@@ -67,7 +66,6 @@
6766
import software.amazon.awssdk.services.json.model.EventStreamOperationWithOnlyOutputRequest;
6867
import software.amazon.awssdk.services.json.model.EventStreamOperationWithOnlyOutputResponse;
6968
import software.amazon.awssdk.services.json.model.EventStreamOperationWithOnlyOutputResponseHandler;
70-
import software.amazon.awssdk.services.json.model.EventTwo;
7169
import software.amazon.awssdk.services.json.model.GetWithoutRequiredMembersRequest;
7270
import software.amazon.awssdk.services.json.model.GetWithoutRequiredMembersResponse;
7371
import software.amazon.awssdk.services.json.model.InputEvent;
@@ -304,9 +302,9 @@ public CompletableFuture<Void> eventStreamOperation(EventStreamOperationRequest
304302

305303
HttpResponseHandler<? extends EventStream> eventResponseHandler = protocolFactory.createResponseHandler(
306304
JsonOperationMetadata.builder().isPayloadJson(true).hasStreamingSuccessResponse(false).build(),
307-
EventStreamTaggedUnionPojoSupplier.builder().putSdkPojoSupplier("EventOne", EventOne::builder)
308-
.putSdkPojoSupplier("EventTheSecond", EventTwo::builder)
309-
.putSdkPojoSupplier("secondEventOne", EventOne::builder)
305+
EventStreamTaggedUnionPojoSupplier.builder().putSdkPojoSupplier("EventOne", EventStream::eventOneBuilder)
306+
.putSdkPojoSupplier("EventTheSecond", EventStream::eventTheSecondBuilder)
307+
.putSdkPojoSupplier("secondEventOne", EventStream::secondEventOneBuilder)
310308
.defaultSdkPojoSupplier(() -> new SdkPojoBuilder(EventStream.UNKNOWN)).build());
311309

312310
HttpResponseHandler<AwsServiceException> errorResponseHandler = createErrorResponseHandler(protocolFactory,
@@ -467,9 +465,9 @@ public CompletableFuture<Void> eventStreamOperationWithOnlyOutput(
467465

468466
HttpResponseHandler<? extends EventStream> eventResponseHandler = protocolFactory.createResponseHandler(
469467
JsonOperationMetadata.builder().isPayloadJson(true).hasStreamingSuccessResponse(false).build(),
470-
EventStreamTaggedUnionPojoSupplier.builder().putSdkPojoSupplier("EventOne", EventOne::builder)
471-
.putSdkPojoSupplier("EventTheSecond", EventTwo::builder)
472-
.putSdkPojoSupplier("secondEventOne", EventOne::builder)
468+
EventStreamTaggedUnionPojoSupplier.builder().putSdkPojoSupplier("EventOne", EventStream::eventOneBuilder)
469+
.putSdkPojoSupplier("EventTheSecond", EventStream::eventTheSecondBuilder)
470+
.putSdkPojoSupplier("secondEventOne", EventStream::secondEventOneBuilder)
473471
.defaultSdkPojoSupplier(() -> new SdkPojoBuilder(EventStream.UNKNOWN)).build());
474472

475473
HttpResponseHandler<AwsServiceException> errorResponseHandler = createErrorResponseHandler(protocolFactory,

codegen/src/test/resources/software/amazon/awssdk/codegen/poet/transform/eventonemarshaller.java

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,7 @@
1919
@SdkInternalApi
2020
public class EventOneMarshaller implements Marshaller<EventOne> {
2121
private static final OperationInfo SDK_OPERATION_BINDING = OperationInfo.builder().hasExplicitPayloadMember(false)
22-
.hasPayloadMembers(true).httpMethod(SdkHttpMethod.GET).hasEvent(true).build();
22+
.hasPayloadMembers(true).httpMethod(SdkHttpMethod.GET).hasEvent(true).build();
2323

2424
private final BaseAwsJsonProtocolFactory protocolFactory;
2525

@@ -32,11 +32,13 @@ public SdkHttpFullRequest marshall(EventOne eventOne) {
3232
Validate.paramNotNull(eventOne, "eventOne");
3333
try {
3434
ProtocolMarshaller<SdkHttpFullRequest> protocolMarshaller = protocolFactory
35-
.createProtocolMarshaller(SDK_OPERATION_BINDING);
35+
.createProtocolMarshaller(SDK_OPERATION_BINDING);
3636
return protocolMarshaller.marshall(eventOne).toBuilder().putHeader(":message-type", "event")
37-
.putHeader(":event-type", "EventOne").putHeader(":content-type", "application/json").build();
37+
.putHeader(":event-type", eventOne.sdkEventType().toString()).putHeader(":content-type", "application/json")
38+
.build();
3839
} catch (Exception e) {
3940
throw SdkClientException.builder().message("Unable to marshall request to JSON: " + e.getMessage()).cause(e).build();
4041
}
4142
}
4243
}
44+

codegen/src/test/resources/software/amazon/awssdk/codegen/poet/transform/eventthreemarshaller.java

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,8 @@
1919
@SdkInternalApi
2020
public class EventThreeMarshaller implements Marshaller<EventThree> {
2121
private static final OperationInfo SDK_OPERATION_BINDING = OperationInfo.builder().hasExplicitPayloadMember(false)
22-
.hasPayloadMembers(true).httpMethod(SdkHttpMethod.GET).hasEvent(true).build();
22+
.hasPayloadMembers(true).httpMethod(SdkHttpMethod.GET).hasEvent(true).build();
23+
2324
private final BaseAwsJsonProtocolFactory protocolFactory;
2425

2526
public EventThreeMarshaller(BaseAwsJsonProtocolFactory protocolFactory) {
@@ -33,7 +34,8 @@ public SdkHttpFullRequest marshall(EventThree eventThree) {
3334
ProtocolMarshaller<SdkHttpFullRequest> protocolMarshaller = protocolFactory
3435
.createProtocolMarshaller(SDK_OPERATION_BINDING);
3536
return protocolMarshaller.marshall(eventThree).toBuilder().putHeader(":message-type", "event")
36-
.putHeader(":event-type", "EventThree").putHeader(":content-type", "application/json").build();
37+
.putHeader(":event-type", eventThree.sdkEventType().toString())
38+
.putHeader(":content-type", "application/json").build();
3739
} catch (Exception e) {
3840
throw SdkClientException.builder().message("Unable to marshall request to JSON: " + e.getMessage()).cause(e).build();
3941
}

codegen/src/test/resources/software/amazon/awssdk/codegen/poet/transform/eventtwomarshaller.java

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,7 @@
1919
@SdkInternalApi
2020
public class EventTwoMarshaller implements Marshaller<EventTwo> {
2121
private static final OperationInfo SDK_OPERATION_BINDING = OperationInfo.builder().hasExplicitPayloadMember(false)
22-
.hasPayloadMembers(true).httpMethod(SdkHttpMethod.GET).hasEvent(true).build();
22+
.hasPayloadMembers(true).httpMethod(SdkHttpMethod.GET).hasEvent(true).build();
2323

2424
private final BaseAwsJsonProtocolFactory protocolFactory;
2525

@@ -32,11 +32,13 @@ public SdkHttpFullRequest marshall(EventTwo eventTwo) {
3232
Validate.paramNotNull(eventTwo, "eventTwo");
3333
try {
3434
ProtocolMarshaller<SdkHttpFullRequest> protocolMarshaller = protocolFactory
35-
.createProtocolMarshaller(SDK_OPERATION_BINDING);
35+
.createProtocolMarshaller(SDK_OPERATION_BINDING);
3636
return protocolMarshaller.marshall(eventTwo).toBuilder().putHeader(":message-type", "event")
37-
.putHeader(":event-type", "EventTwo").putHeader(":content-type", "application/json").build();
37+
.putHeader(":event-type", eventTwo.sdkEventType().toString()).putHeader(":content-type", "application/json")
38+
.build();
3839
} catch (Exception e) {
3940
throw SdkClientException.builder().message("Unable to marshall request to JSON: " + e.getMessage()).cause(e).build();
4041
}
4142
}
4243
}
44+

codegen/src/test/resources/software/amazon/awssdk/codegen/poet/transform/inputeventmarshaller.java

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,7 @@
1919
@SdkInternalApi
2020
public class InputEventMarshaller implements Marshaller<InputEvent> {
2121
private static final OperationInfo SDK_OPERATION_BINDING = OperationInfo.builder().hasExplicitPayloadMember(true)
22-
.hasPayloadMembers(true).httpMethod(SdkHttpMethod.GET).hasEvent(true).build();
22+
.hasPayloadMembers(true).httpMethod(SdkHttpMethod.GET).hasEvent(true).build();
2323

2424
private final BaseAwsJsonProtocolFactory protocolFactory;
2525

@@ -32,11 +32,13 @@ public SdkHttpFullRequest marshall(InputEvent inputEvent) {
3232
Validate.paramNotNull(inputEvent, "inputEvent");
3333
try {
3434
ProtocolMarshaller<SdkHttpFullRequest> protocolMarshaller = protocolFactory
35-
.createProtocolMarshaller(SDK_OPERATION_BINDING);
35+
.createProtocolMarshaller(SDK_OPERATION_BINDING);
3636
return protocolMarshaller.marshall(inputEvent).toBuilder().putHeader(":message-type", "event")
37-
.putHeader(":event-type", "InputEvent").putHeader(":content-type", "application/octet-stream").build();
37+
.putHeader(":event-type", inputEvent.sdkEventType().toString())
38+
.putHeader(":content-type", "application/octet-stream").build();
3839
} catch (Exception e) {
3940
throw SdkClientException.builder().message("Unable to marshall request to JSON: " + e.getMessage()).cause(e).build();
4041
}
4142
}
4243
}
44+

codegen/src/test/resources/software/amazon/awssdk/codegen/poet/transform/inputeventtwomarshaller.java

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,7 @@
1919
@SdkInternalApi
2020
public class InputEventTwoMarshaller implements Marshaller<InputEventTwo> {
2121
private static final OperationInfo SDK_OPERATION_BINDING = OperationInfo.builder().hasExplicitPayloadMember(false)
22-
.hasPayloadMembers(true).httpMethod(SdkHttpMethod.GET).hasEvent(true).build();
22+
.hasPayloadMembers(true).httpMethod(SdkHttpMethod.GET).hasEvent(true).build();
2323

2424
private final BaseAwsJsonProtocolFactory protocolFactory;
2525

@@ -32,11 +32,13 @@ public SdkHttpFullRequest marshall(InputEventTwo inputEventTwo) {
3232
Validate.paramNotNull(inputEventTwo, "inputEventTwo");
3333
try {
3434
ProtocolMarshaller<SdkHttpFullRequest> protocolMarshaller = protocolFactory
35-
.createProtocolMarshaller(SDK_OPERATION_BINDING);
35+
.createProtocolMarshaller(SDK_OPERATION_BINDING);
3636
return protocolMarshaller.marshall(inputEventTwo).toBuilder().putHeader(":message-type", "event")
37-
.putHeader(":event-type", "InputEventTwo").putHeader(":content-type", "application/json").build();
37+
.putHeader(":event-type", inputEventTwo.sdkEventType().toString())
38+
.putHeader(":content-type", "application/json").build();
3839
} catch (Exception e) {
3940
throw SdkClientException.builder().message("Unable to marshall request to JSON: " + e.getMessage()).cause(e).build();
4041
}
4142
}
4243
}
44+

0 commit comments

Comments
 (0)