microsoftgraph / microsoftgraph/msgraph-sdk-java-core
Batch response: Improved error handling when "UserCollectionResponse" is returned but discrimiator is set to "User"
Nobody has claimed this yet.
- Dominant language
- Java
- Stars
- 67
- Forks
- 34
- PR merge metrics
- No merged PRs in 30d
Description
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)
Contributor guide
First steps
- Read the whole issue, then the project's contributing guide.
- Comment on the issue to say you are picking it up — it saves two people doing the same work.
- Fork the repository and make your change on a branch.
- Open a pull request that references the issue number.
Research direction
Start with com.microsoft.graph.core.requests.ResponseBodyHandler#handleResponse and trace how the nested body of a POST $batch response is passed to the parse node. Review BatchResponseContentCollection#getResponseById and the provided nested JSON reproduction. Done means nested UserCollectionResponse objects are parsed correctly, with an appropriate failure for responses that cannot be parsed.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- java
- Domain
- api, backend
- Issue type
- Bug
- Difficulty
- 4/5
- Estimated time
- 3-5 days
- Activity status
- Stale
- Clarity
- Mostly clear
- Newbie friendliness
- 35/100