Skip to content

Don't create object if no implicit members #2773

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -187,11 +187,17 @@ public List<MemberModel> getUnboundMembers() {
List<MemberModel> unboundMembers = new ArrayList<>();
if (members != null) {
for (MemberModel member : members) {
if (member.getHttp().getLocation() == null) {
if (member.getHttp().getLocation() == null && !member.getHttp().getIsPayload()) {
if (hasPayloadMember) {
// There is an explicit payload, but this unbound
// member isn't it.
// Note: Somewhat unintuitive, explicit payloads don't
// have an explicit location; they're identified by
// the payload HTTP trait being true.
throw new IllegalStateException(String.format(
"C2J Shape %s has both an explicit payload member and unbound (no explicit location) members. "
+ "This is undefined behavior, verify the correctness of the C2J model", c2jName));
"C2J Shape %s has both an explicit payload member and unbound (no explicit location) member, %s."
+ " This is undefined behavior, verify the correctness of the C2J model.",
c2jName, member.getName()));
}
unboundMembers.add(member);
}
Expand Down Expand Up @@ -221,7 +227,12 @@ public List<MemberModel> getUnboundEventMembers() {
public boolean hasPayloadMembers() {
return hasPayloadMember ||
getExplicitEventPayloadMember() != null ||
!getUnboundMembers().isEmpty() ||
hasImplicitPayloadMembers();

}

public boolean hasImplicitPayloadMembers() {
return !getUnboundMembers().isEmpty() ||
(isEvent() && !getUnboundEventMembers().isEmpty());
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -95,6 +95,7 @@ protected FieldSpec operationInfoField() {
.add(".httpMethod($T.$L)", SdkHttpMethod.class, shapeModel.getMarshaller().getVerb())
.add(".hasExplicitPayloadMember($L)", shapeModel.isHasPayloadMember() ||
shapeModel.getExplicitEventPayloadMember() != null)
.add(".hasImplicitPayloadMembers($L)", shapeModel.hasImplicitPayloadMembers())
.add(".hasPayloadMembers($L)", shapeModel.hasPayloadMembers());

if (StringUtils.isNotBlank(shapeModel.getMarshaller().getTarget())) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,8 @@
@SdkInternalApi
public class AllTypesRequestMarshaller implements Marshaller<AllTypesRequest> {
private static final OperationInfo SDK_OPERATION_BINDING = OperationInfo.builder().requestUri("/")
.httpMethod(SdkHttpMethod.POST).hasExplicitPayloadMember(false).hasPayloadMembers(true).build();
.httpMethod(SdkHttpMethod.POST).hasExplicitPayloadMember(false).hasImplicitPayloadMembers(true)
.hasPayloadMembers(true).build();

private final BaseAwsJsonProtocolFactory protocolFactory;

Expand All @@ -32,11 +33,10 @@ public SdkHttpFullRequest marshall(AllTypesRequest allTypesRequest) {
Validate.paramNotNull(allTypesRequest, "allTypesRequest");
try {
ProtocolMarshaller<SdkHttpFullRequest> protocolMarshaller = protocolFactory
.createProtocolMarshaller(SDK_OPERATION_BINDING);
.createProtocolMarshaller(SDK_OPERATION_BINDING);
return protocolMarshaller.marshall(allTypesRequest);
} catch (Exception e) {
throw SdkClientException.builder().message("Unable to marshall request to JSON: " + e.getMessage()).cause(e).build();
}
}
}

Original file line number Diff line number Diff line change
Expand Up @@ -19,8 +19,8 @@
@SdkInternalApi
public class EventStreamOperationRequestMarshaller implements Marshaller<EventStreamOperationRequest> {
private static final OperationInfo SDK_OPERATION_BINDING = OperationInfo.builder()
.requestUri("/2016-03-11/eventStreamOperation").httpMethod(SdkHttpMethod.POST).hasExplicitPayloadMember(true)
.hasPayloadMembers(true).hasEventStreamingInput(true).build();
.requestUri("/2016-03-11/eventStreamOperation").httpMethod(SdkHttpMethod.POST).hasExplicitPayloadMember(true)
.hasImplicitPayloadMembers(false).hasPayloadMembers(true).hasEventStreamingInput(true).build();

private final BaseAwsJsonProtocolFactory protocolFactory;

Expand All @@ -33,7 +33,7 @@ public SdkHttpFullRequest marshall(EventStreamOperationRequest eventStreamOperat
Validate.paramNotNull(eventStreamOperationRequest, "eventStreamOperationRequest");
try {
ProtocolMarshaller<SdkHttpFullRequest> protocolMarshaller = protocolFactory
.createProtocolMarshaller(SDK_OPERATION_BINDING);
.createProtocolMarshaller(SDK_OPERATION_BINDING);
return protocolMarshaller.marshall(eventStreamOperationRequest);
} catch (Exception e) {
throw SdkClientException.builder().message("Unable to marshall request to JSON: " + e.getMessage()).cause(e).build();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,11 +17,11 @@
*/
@Generated("software.amazon.awssdk:codegen")
@SdkInternalApi
public class EventStreamOperationWithOnlyInputRequestMarshaller implements
Marshaller<EventStreamOperationWithOnlyInputRequest> {
public class EventStreamOperationWithOnlyInputRequestMarshaller implements Marshaller<EventStreamOperationWithOnlyInputRequest> {
private static final OperationInfo SDK_OPERATION_BINDING = OperationInfo.builder()
.requestUri("/2016-03-11/EventStreamOperationWithOnlyInput").httpMethod(SdkHttpMethod.POST)
.hasExplicitPayloadMember(false).hasPayloadMembers(true).hasEventStreamingInput(true).build();
.requestUri("/2016-03-11/EventStreamOperationWithOnlyInput").httpMethod(SdkHttpMethod.POST)
.hasExplicitPayloadMember(false).hasImplicitPayloadMembers(true).hasPayloadMembers(true).hasEventStreamingInput(true)
.build();

private final BaseAwsJsonProtocolFactory protocolFactory;

Expand All @@ -34,11 +34,10 @@ public SdkHttpFullRequest marshall(EventStreamOperationWithOnlyInputRequest even
Validate.paramNotNull(eventStreamOperationWithOnlyInputRequest, "eventStreamOperationWithOnlyInputRequest");
try {
ProtocolMarshaller<SdkHttpFullRequest> protocolMarshaller = protocolFactory
.createProtocolMarshaller(SDK_OPERATION_BINDING);
.createProtocolMarshaller(SDK_OPERATION_BINDING);
return protocolMarshaller.marshall(eventStreamOperationWithOnlyInputRequest);
} catch (Exception e) {
throw SdkClientException.builder().message("Unable to marshall request to JSON: " + e.getMessage()).cause(e).build();
}
}
}

Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,8 @@
@SdkInternalApi
public class NestedContainersRequestMarshaller implements Marshaller<NestedContainersRequest> {
private static final OperationInfo SDK_OPERATION_BINDING = OperationInfo.builder().requestUri("/")
.httpMethod(SdkHttpMethod.POST).hasExplicitPayloadMember(false).hasPayloadMembers(true).build();
.httpMethod(SdkHttpMethod.POST).hasExplicitPayloadMember(false).hasImplicitPayloadMembers(true)
.hasPayloadMembers(true).build();

private final BaseAwsJsonProtocolFactory protocolFactory;

Expand All @@ -32,11 +33,10 @@ public SdkHttpFullRequest marshall(NestedContainersRequest nestedContainersReque
Validate.paramNotNull(nestedContainersRequest, "nestedContainersRequest");
try {
ProtocolMarshaller<SdkHttpFullRequest> protocolMarshaller = protocolFactory
.createProtocolMarshaller(SDK_OPERATION_BINDING);
.createProtocolMarshaller(SDK_OPERATION_BINDING);
return protocolMarshaller.marshall(nestedContainersRequest);
} catch (Exception e) {
throw SdkClientException.builder().message("Unable to marshall request to JSON: " + e.getMessage()).cause(e).build();
}
}
}

Original file line number Diff line number Diff line change
Expand Up @@ -17,10 +17,10 @@
*/
@Generated("software.amazon.awssdk:codegen")
@SdkInternalApi
public class OperationWithNoInputOrOutputRequestMarshaller implements
Marshaller<OperationWithNoInputOrOutputRequest> {
public class OperationWithNoInputOrOutputRequestMarshaller implements Marshaller<OperationWithNoInputOrOutputRequest> {
private static final OperationInfo SDK_OPERATION_BINDING = OperationInfo.builder().requestUri("/")
.httpMethod(SdkHttpMethod.POST).hasExplicitPayloadMember(false).hasPayloadMembers(false).build();
.httpMethod(SdkHttpMethod.POST).hasExplicitPayloadMember(false).hasImplicitPayloadMembers(false)
.hasPayloadMembers(false).build();

private final BaseAwsJsonProtocolFactory protocolFactory;

Expand All @@ -33,11 +33,10 @@ public SdkHttpFullRequest marshall(OperationWithNoInputOrOutputRequest operation
Validate.paramNotNull(operationWithNoInputOrOutputRequest, "operationWithNoInputOrOutputRequest");
try {
ProtocolMarshaller<SdkHttpFullRequest> protocolMarshaller = protocolFactory
.createProtocolMarshaller(SDK_OPERATION_BINDING);
.createProtocolMarshaller(SDK_OPERATION_BINDING);
return protocolMarshaller.marshall(operationWithNoInputOrOutputRequest);
} catch (Exception e) {
throw SdkClientException.builder().message("Unable to marshall request to JSON: " + e.getMessage()).cause(e).build();
}
}
}

Original file line number Diff line number Diff line change
Expand Up @@ -19,8 +19,8 @@
@SdkInternalApi
public class StreamingInputOperationRequestMarshaller implements Marshaller<StreamingInputOperationRequest> {
private static final OperationInfo SDK_OPERATION_BINDING = OperationInfo.builder()
.requestUri("/2016-03-11/streamingInputOperation").httpMethod(SdkHttpMethod.POST).hasExplicitPayloadMember(true)
.hasPayloadMembers(true).hasStreamingInput(true).build();
.requestUri("/2016-03-11/streamingInputOperation").httpMethod(SdkHttpMethod.POST).hasExplicitPayloadMember(true)
.hasImplicitPayloadMembers(false).hasPayloadMembers(true).hasStreamingInput(true).build();

private final BaseAwsJsonProtocolFactory protocolFactory;

Expand All @@ -33,11 +33,10 @@ public SdkHttpFullRequest marshall(StreamingInputOperationRequest streamingInput
Validate.paramNotNull(streamingInputOperationRequest, "streamingInputOperationRequest");
try {
ProtocolMarshaller<SdkHttpFullRequest> protocolMarshaller = protocolFactory
.createProtocolMarshaller(SDK_OPERATION_BINDING);
.createProtocolMarshaller(SDK_OPERATION_BINDING);
return protocolMarshaller.marshall(streamingInputOperationRequest);
} catch (Exception e) {
throw SdkClientException.builder().message("Unable to marshall request to JSON: " + e.getMessage()).cause(e).build();
}
}
}

Original file line number Diff line number Diff line change
Expand Up @@ -19,8 +19,8 @@
@SdkInternalApi
public class StreamingOutputOperationRequestMarshaller implements Marshaller<StreamingOutputOperationRequest> {
private static final OperationInfo SDK_OPERATION_BINDING = OperationInfo.builder()
.requestUri("/2016-03-11/streamingOutputOperation").httpMethod(SdkHttpMethod.POST).hasExplicitPayloadMember(false)
.hasPayloadMembers(false).build();
.requestUri("/2016-03-11/streamingOutputOperation").httpMethod(SdkHttpMethod.POST).hasExplicitPayloadMember(false)
.hasImplicitPayloadMembers(false).hasPayloadMembers(false).build();

private final BaseAwsJsonProtocolFactory protocolFactory;

Expand All @@ -33,11 +33,10 @@ public SdkHttpFullRequest marshall(StreamingOutputOperationRequest streamingOutp
Validate.paramNotNull(streamingOutputOperationRequest, "streamingOutputOperationRequest");
try {
ProtocolMarshaller<SdkHttpFullRequest> protocolMarshaller = protocolFactory
.createProtocolMarshaller(SDK_OPERATION_BINDING);
.createProtocolMarshaller(SDK_OPERATION_BINDING);
return protocolMarshaller.marshall(streamingOutputOperationRequest);
} catch (Exception e) {
throw SdkClientException.builder().message("Unable to marshall request to JSON: " + e.getMessage()).cause(e).build();
}
}
}

Original file line number Diff line number Diff line change
Expand Up @@ -62,6 +62,7 @@ public class JsonProtocolMarshaller implements ProtocolMarshaller<SdkHttpFullReq
private final String contentType;
private final AwsJsonProtocolMetadata protocolMetadata;
private final boolean hasExplicitPayloadMember;
private final boolean hasImplicitPayloadMembers;
private final boolean hasStreamingInput;

private final JsonMarshallerContext marshallerContext;
Expand All @@ -78,6 +79,7 @@ public class JsonProtocolMarshaller implements ProtocolMarshaller<SdkHttpFullReq
this.contentType = contentType;
this.protocolMetadata = protocolMetadata;
this.hasExplicitPayloadMember = operationInfo.hasExplicitPayloadMember();
this.hasImplicitPayloadMembers = operationInfo.hasImplicitPayloadMembers();
this.hasStreamingInput = operationInfo.hasStreamingInput();
this.hasEventStreamingInput = operationInfo.hasEventStreamingInput();
this.hasEvent = operationInfo.hasEvent();
Expand Down Expand Up @@ -167,7 +169,8 @@ private SdkHttpFullRequest.Builder fillBasicRequestParams(OperationInfo operatio
* members bound to the payload will be added as fields to this object.
*/
private void startMarshalling() {
if (!hasExplicitPayloadMember) {
// Create the implicit request object if needed.
if (needTopLevelJsonObject()) {
jsonGenerator.writeStartObject();
}
}
Expand Down Expand Up @@ -220,7 +223,7 @@ private SdkHttpFullRequest finishMarshalling() {
// Content may already be set if the payload is binary data.
if (request.contentStreamProvider() == null) {
// End the implicit request object if needed.
if (!hasExplicitPayloadMember) {
if (needTopLevelJsonObject()) {
jsonGenerator.writeEndObject();
}

Expand Down Expand Up @@ -263,4 +266,10 @@ private void marshallField(SdkField<?> field, Object val) {
MARSHALLER_REGISTRY.getMarshaller(field.location(), field.marshallingType(), val)
.marshall(val, marshallerContext, field.locationName(), (SdkField<Object>) field);
}

private boolean needTopLevelJsonObject() {
return AwsJsonProtocol.AWS_JSON.equals(protocolMetadata.protocol())
|| (!hasExplicitPayloadMember && hasImplicitPayloadMembers);

}
}
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@ public final class OperationInfo {
private final String apiVersion;
private final boolean hasExplicitPayloadMember;
private final boolean hasPayloadMembers;
private final boolean hasImplicitPayloadMembers;
private final boolean hasStreamingInput;
private final boolean hasEventStreamingInput;
private final boolean hasEvent;
Expand All @@ -42,6 +43,7 @@ private OperationInfo(Builder builder) {
this.operationIdentifier = builder.operationIdentifier;
this.apiVersion = builder.apiVersion;
this.hasExplicitPayloadMember = builder.hasExplicitPayloadMember;
this.hasImplicitPayloadMembers = builder.hasImplicitPayloadMembers;
this.hasPayloadMembers = builder.hasPayloadMembers;
this.hasStreamingInput = builder.hasStreamingInput;
this.additionalMetadata = builder.additionalMetadata.build();
Expand Down Expand Up @@ -95,6 +97,14 @@ public boolean hasPayloadMembers() {
return hasPayloadMembers;
}

/**
* @return True if the operation has members that are not explicitly bound to a marshalling location, and thus are
* implicitly bound to the body.
*/
public boolean hasImplicitPayloadMembers() {
return hasImplicitPayloadMembers;
}

/**
* @return True if the operation has streaming input.
*/
Expand Down Expand Up @@ -144,6 +154,7 @@ public static final class Builder {
private String operationIdentifier;
private String apiVersion;
private boolean hasExplicitPayloadMember;
private boolean hasImplicitPayloadMembers;
private boolean hasPayloadMembers;
private boolean hasStreamingInput;
private boolean hasEventStreamingInput;
Expand Down Expand Up @@ -183,6 +194,11 @@ public Builder hasPayloadMembers(boolean hasPayloadMembers) {
return this;
}

public Builder hasImplicitPayloadMembers(boolean hasImplicitPayloadMembers) {
this.hasImplicitPayloadMembers = hasImplicitPayloadMembers;
return this;
}

public Builder hasStreamingInput(boolean hasStreamingInput) {
this.hasStreamingInput = hasStreamingInput;
return this;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -219,6 +219,60 @@
}
}
},
{
"description": "NoPayloadGet",
"given": {
"input": {
}
},
"when": {
"action": "marshall",
"operation": "NoPayloadPost"
},
"then": {
"serializedAs": {
"uri": "/no-payload",
"method": "POST",
"headers": {
"doesNotContain": [
"Content-Type"
]
},
"body": {
"equals": ""
}
}
}
},
{
"description": "NoPayloadGetWithHeader",
"given": {
"input": {
"testId": "t-12345"
}
},
"when": {
"action": "marshall",
"operation": "NoPayloadPost"
},
"then": {
"serializedAs": {
"uri": "/no-payload",
"method": "POST",
"headers": {
"contains": {
"x-amz-test-id": "t-12345"
},
"doesNotContain": [
"Content-Type"
]
},
"body": {
"equals": ""
}
}
}
},
{
"description": "TestBodyNoParams",
"given": {
Expand Down
Loading