Skip to content

Commit be81185

Browse files
John Viegasjoviegas
John Viegas
authored andcommitted
Support to UnMarshall Blob type payload data in XMlProtocol
1 parent 0930a8e commit be81185

File tree

5 files changed

+53
-23
lines changed

5 files changed

+53
-23
lines changed

core/protocols/aws-xml-protocol/src/main/java/software/amazon/awssdk/protocols/xml/internal/unmarshall/XmlProtocolUnmarshaller.java

Lines changed: 13 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -16,13 +16,16 @@
1616
package software.amazon.awssdk.protocols.xml.internal.unmarshall;
1717

1818
import static java.util.Collections.singletonList;
19+
import static software.amazon.awssdk.protocols.xml.internal.unmarshall.XmlResponseParserUtils.getBlobTypePayloadMemberToUnmarshal;
1920

2021
import java.time.Instant;
2122
import java.util.Collections;
2223
import java.util.HashMap;
2324
import java.util.List;
2425
import java.util.Map;
26+
import java.util.Optional;
2527
import software.amazon.awssdk.annotations.SdkInternalApi;
28+
import software.amazon.awssdk.core.SdkBytes;
2629
import software.amazon.awssdk.core.SdkField;
2730
import software.amazon.awssdk.core.SdkPojo;
2831
import software.amazon.awssdk.core.protocol.MarshallLocation;
@@ -76,6 +79,7 @@ public <TypeT extends SdkPojo> TypeT unmarshall(SdkPojo sdkPojo,
7679
}
7780

7881
SdkPojo unmarshall(XmlUnmarshallerContext context, SdkPojo sdkPojo, XmlElement root) {
82+
Optional<SdkField<?>> payloadMemberAsBlobType = getBlobTypePayloadMemberToUnmarshal(sdkPojo);
7983
for (SdkField<?> field : sdkPojo.sdkFields()) {
8084
XmlUnmarshaller<Object> unmarshaller = REGISTRY.getUnmarshaller(field.location(), field.marshallingType());
8185

@@ -94,8 +98,15 @@ SdkPojo unmarshall(XmlUnmarshallerContext context, SdkPojo sdkPojo, XmlElement r
9498
root.getElementsByName(field.unmarshallLocationName());
9599

96100
if (!CollectionUtils.isNullOrEmpty(element)) {
97-
Object unmarshalled = unmarshaller.unmarshall(context, element, (SdkField<Object>) field);
98-
field.set(sdkPojo, unmarshalled);
101+
boolean isFieldBlobTypePayload = payloadMemberAsBlobType.isPresent()
102+
&& payloadMemberAsBlobType.get().equals(field);
103+
104+
if (isFieldBlobTypePayload) {
105+
field.set(sdkPojo, SdkBytes.fromInputStream(context.response().content().get()));
106+
} else {
107+
Object unmarshalled = unmarshaller.unmarshall(context, element, (SdkField<Object>) field);
108+
field.set(sdkPojo, unmarshalled);
109+
}
99110
}
100111
}
101112
} else {

core/protocols/aws-xml-protocol/src/main/java/software/amazon/awssdk/protocols/xml/internal/unmarshall/XmlResponseParserUtils.java

Lines changed: 21 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -19,8 +19,11 @@
1919

2020
import java.util.Optional;
2121
import software.amazon.awssdk.annotations.SdkInternalApi;
22+
import software.amazon.awssdk.core.SdkField;
2223
import software.amazon.awssdk.core.SdkPojo;
2324
import software.amazon.awssdk.core.protocol.MarshallLocation;
25+
import software.amazon.awssdk.core.protocol.MarshallingType;
26+
import software.amazon.awssdk.core.traits.PayloadTrait;
2427
import software.amazon.awssdk.http.AbortableInputStream;
2528
import software.amazon.awssdk.http.SdkHttpFullResponse;
2629
import software.amazon.awssdk.protocols.query.unmarshall.XmlDomParser;
@@ -49,7 +52,7 @@ public static XmlElement parse(SdkPojo sdkPojo, SdkHttpFullResponse response) {
4952
// In some cases the responseContent is present but empty, so when we are not expecting a body we should
5053
// not attempt to parse it even if the body appears to be present.
5154
if ((!response.isSuccessful() || hasPayloadMembers(sdkPojo)) && responseContent.isPresent() &&
52-
!contentLengthZero(response)) {
55+
!contentLengthZero(response) && !getBlobTypePayloadMemberToUnmarshal(sdkPojo).isPresent()) {
5356
return XmlDomParser.parse(responseContent.get());
5457
} else {
5558
return XmlElement.empty();
@@ -63,6 +66,21 @@ public static XmlElement parse(SdkPojo sdkPojo, SdkHttpFullResponse response) {
6366
}
6467
}
6568

69+
/**
70+
* Gets the Member which is a Payload and which is of Blob Type.
71+
* @param sdkPojo
72+
* @return Optional of SdkField member if member is Blob type payload else returns Empty.
73+
*/
74+
public static Optional<SdkField<?>> getBlobTypePayloadMemberToUnmarshal(SdkPojo sdkPojo) {
75+
return sdkPojo.sdkFields().stream()
76+
.filter(e -> isExplicitPayloadMember(e))
77+
.filter(f -> f.marshallingType() == MarshallingType.SDK_BYTES).findFirst();
78+
}
79+
80+
private static boolean isExplicitPayloadMember(SdkField<?> f) {
81+
return f.containsTrait(PayloadTrait.class);
82+
}
83+
6684
private static boolean hasPayloadMembers(SdkPojo sdkPojo) {
6785
return sdkPojo.sdkFields().stream()
6886
.anyMatch(f -> f.location() == MarshallLocation.PAYLOAD);
@@ -71,4 +89,6 @@ private static boolean hasPayloadMembers(SdkPojo sdkPojo) {
7189
private static boolean contentLengthZero(SdkHttpFullResponse response) {
7290
return response.firstMatchingHeader(CONTENT_LENGTH).map(l -> Long.parseLong(l) == 0).orElse(false);
7391
}
92+
93+
7494
}

test/protocol-tests-core/src/main/resources/software/amazon/awssdk/protocol/suites/cases/rest-core-output.json

Lines changed: 19 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -119,8 +119,26 @@
119119
"deserializedAs": {
120120
}
121121
}
122-
}
122+
},
123123
// TODO header maps, service models supports this but Java SDK does not (not currently exercised)
124124
// TODO header maps with prefix, services models do not support this, only used by S3
125125
// TODO List of strings bound to header, service models supports this, not currently exercised by any service
126+
{
127+
"description": "Operation with explicit payload blob in output is unmarshalled correctly",
128+
"given": {
129+
"response": {
130+
"status_code": 200,
131+
"body": "contents"
132+
}
133+
},
134+
"when": {
135+
"action": "unmarshall",
136+
"operation": "OperationWithExplicitPayloadBlob"
137+
},
138+
"then": {
139+
"deserializedAs": {
140+
"PayloadMember": "contents"
141+
}
142+
}
143+
}
126144
]

test/protocol-tests-core/src/main/resources/software/amazon/awssdk/protocol/suites/cases/rest-json-output.json

Lines changed: 0 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -19,25 +19,6 @@
1919
}
2020
}
2121
},
22-
// TODO payload blob and streaming should be moved up to rest-core when Java supports it
23-
{
24-
"description": "Operation with explicit payload blob in output is unmarshalled correctly",
25-
"given": {
26-
"response": {
27-
"status_code": 200,
28-
"body": "contents"
29-
}
30-
},
31-
"when": {
32-
"action": "unmarshall",
33-
"operation": "OperationWithExplicitPayloadBlob"
34-
},
35-
"then": {
36-
"deserializedAs": {
37-
"PayloadMember": "contents"
38-
}
39-
}
40-
},
4122
{
4223
"description": "Operation with streaming payload in output is unmarshalled correctly",
4324
"given": {

0 commit comments

Comments
 (0)