msgraph-sdk-java-core
msgraph-sdk-java-core copied to clipboard
Batch response: Improved error handling when "UserCollectionResponse" is returned but discrimiator is set to "User"
Graph Core Version: 3.1.9 Kiota Version: 1.1.7 Affected Method: com.microsoft.graph.core.requests.ResponseBodyHandler#handleResponse
Edit: Added a comment explaining the reason of this behavior and changed the issue title.
Microsoft Graph core returns an object with all properties set to null, if the response body contains a nested structure.
Expected behavior
com.microsoft.graph.core.requests.ResponseBodyHandler#handleResponse
should parse nested response objects. And maybe throw an error if a response can not be parsed.
Actual behavior
com.microsoft.graph.core.requests.ResponseBodyHandler#handleResponse
returns a object with all properties set to null
.
Steps to reproduce the behavior
Execute the following request using the Graph API: POST https://graph.microsoft.com/v1.0/$batch
Body is GET users?$filter=identities/any(c:c/issuerAssignedId eq '<the issuer Assigned id>' and c/issuer eq 'contoso.com')&$select=id,displayName,email,UserPrincipalName,identities,accountEnabled
{
"requests": [
{
"id": "d26195f1-aa54-461f-9119-aa98687ea27e",
"url": "/users?%24filter=identities%2Fany% ... ",
"method": "GET",
"headers": {
"accept": "application/json"
}
}
]
}
Response: shortended just to show the structure. Note the nested structure in the body which causes the erroneous behavior.
{
"responses": [
{
"id": "766378b9-df71-473d-909a-da07fa9f10c5",
"status": 200,
"headers": {...},
"body": {
"@odata.context": "https://graph.microsoft.com/v1.0/$metadata#users(id,displayName,email,userPrincipalName,identities,accountEnabled)",
"value": [
{
"id": "<some Id>",
"displayName": "John Doe",
"userPrincipalName": "cpim_something",
"accountEnabled": false,
"identities": [...]
}
]
}
}
]
}
The image shows the structure of parseNode
in com.microsoft.graph.core.requests.ResponseBodyHandler#handleResponse
for a Request that CAN NOT be parsed:
The image shows the structure of parseNode
in com.microsoft.graph.core.requests.ResponseBodyHandler#handleResponse
for a request that CAN be parsed:
Remarks
I verified this by unnesting the structure and re-parsing the response:
ByteArrayInputStream unnestedResponse = new ByteArrayInputStream(((java.util.ArrayList)((JsonArray)((com.google.gson.internal.LinkedTreeMap.Node)((com.google.gson.internal.LinkedTreeMap)((JsonObject)((JsonParseNode)parseNode).currentNode).members).entrySet().toArray()[1]).getValue()).elements).get(0).toString().getBytes());
String contentType = body.contentType().type() + "/" + body.contentType().subtype();
this.parseNodeFactory
.getParseNode(contentType, unnestedResponse)
.getObjectValue(this.factory);
An intermediate fix (not yet tested) could be to provide your own implementation of ResponseBodyHandler
when invoking com.microsoft.graph.core.content.BatchResponseContentCollection#getResponseById(java.lang.String, com.microsoft.kiota.ResponseHandler)