Skip to content
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

Fix bug on atomicityGroup as a dependsOn value in Odata v4 #1822

Closed
KenitoInc opened this issue Jun 24, 2020 · 1 comment
Closed

Fix bug on atomicityGroup as a dependsOn value in Odata v4 #1822

KenitoInc opened this issue Jun 24, 2020 · 1 comment
Assignees
Labels

Comments

@KenitoInc
Copy link
Contributor

KenitoInc commented Jun 24, 2020

atomicityGroup as a dependsOn value fails for Odata v4 requests, but succeeds in Odata v4.01 requests.
In Json batch, we use atomicGroup Id in dependsOn for 2 reasons:

  1. To extract Request ids for use in reference Uris (in v4.01).
  2. Sequence requests so that they are executed in a certain order (in both v4 and v4.01).

The current implementation of dependsOn atomicityGroup is aimed at extracting request Ids for use in reference uris.
This works well in Odata v4.01 but not in Odata v4. This is because in Odata v4, the last request Id in a group is not added to the contentId cache,hence validation fails in the snippets below.

if (dependsOnIds != null)
{
// Validate explicit dependsOnIds cases.
foreach (string id in convertedDependsOnIds)
{
if (!this.payloadUriConverter.ContainsContentId(id))
{
throw new ODataException(Strings.ODataBatchReader_DependsOnIdNotFound(id, contentId));
}
}
}

if (dependsOnRequestIds != null && dependsOnIdsValidationRequired)
{
foreach (string id in dependsOnRequestIds)
{
if (!this.PayloadUriConverter.ContainsContentId(id))
{
throw new ODataException(Strings.ODataBatchReader_DependsOnIdNotFound(id, contentId));
}
}
}

The validations above should not be applicable to v4 since we may want to use atomicity groups to sequence requests without using reference Uris.

Assemblies affected

Microsoft.OData.Core v7.6.4

Reproduce steps

Using postman, make a batch request to an odata service with a payload similar to the one below
POST http://localhost:6143/odata/$batch

{
  "requests": [
    {
      "id": "3",
      "atomicityGroup": "ac92c60b-bbb5-438b-ba1f-db6fbe2ee053",
      "method": "PATCH",
      "url": "http://localhost:6143/odata/Books(1)",
      "headers": {
        "odata-version": "4.0",
        "odata-maxversion": "4.0",
        "content-type": "application/json;odata.metadata=minimal",
        "accept": "application/json;odata.metadata=minimal",
        "accept-charset": "UTF-8",
        "user-agent": "Microsoft.OData.Client/7.7.0"
      },
      "body": {
        "@odata.type": "#OdataService.Book",
        "Id": 1,
        "Isbn": null,
        "Title": "B1",
        "Year": 2001
      }
    },
    {
      "id": "4",
      "atomicityGroup": "a7224f21-60e4-44b7-9c3d-a6718f3f7181",
      "dependsOn": [
        "ac92c60b-bbb5-438b-ba1f-db6fbe2ee053"
      ],
      "method": "PATCH",
      "url": "http://localhost:6143/odata/Books(2)",
      "headers": {
        "odata-version": "4.0",
        "odata-maxversion": "4.0",
        "content-type": "application/json;odata.metadata=minimal",
        "accept": "application/json;odata.metadata=minimal",
        "accept-charset": "UTF-8",
        "user-agent": "Microsoft.OData.Client/7.7.0"
      },
      "body": {
        "@odata.type": "#OdataService.Book",
        "Id": 2,
        "Isbn": null,
        "Title": "B2",
        "Year": 2002
      }
    }
  ]
}

Expected result

Batch request executed successfully.

Actual result

Error 500

System.AggregateException: One or more errors occurred. (One or more errors occurred. (The dependsOn Id: [3] in request [4] is not matching any of the request Id and atomic group Id seen so far. Forward reference is not allowed.))
 ---> System.AggregateException: One or more errors occurred. (The dependsOn Id: [3] in request [4] is not matching any of the request Id and atomic group Id seen so far. Forward reference is not allowed.)
 ---> Microsoft.OData.ODataException: The dependsOn Id: [3] in request [4] is not matching any of the request Id and atomic group Id seen so far. Forward reference is not allowed.
   at Microsoft.OData.ODataBatchReader.BuildOperationRequestMessage(Func`1 streamCreatorFunc, String method, Uri requestUri, ODataBatchOperationHeaders headers, String contentId, String groupId, IEnumerable`1 dependsOnRequestIds, Boolean dependsOnIdsValidationRequired)
   at Microsoft.OData.JsonLight.ODataJsonLightBatchReader.CreateOperationRequestMessageImplementation()
   at Microsoft.OData.TaskUtils.GetTaskForSynchronousOperation[T](Func`1 synchronousOperation)
   --- End of inner exception stack trace ---
   --- End of inner exception stack trace ---
   at Microsoft.AspNet.OData.Batch.ODataBatchReaderExtensions.ReadOperationInternalAsync(ODataBatchReader reader, HttpContext originalContext, Guid batchId, Nullable`1 changeSetId, CancellationToken cancellationToken, Boolean bufferContentStream)
   at Microsoft.AspNet.OData.Batch.ODataBatchReaderExtensions.ReadChangeSetRequestAsync(ODataBatchReader reader, HttpContext context, Guid batchId, CancellationToken cancellationToken)
   at Microsoft.AspNet.OData.Batch.DefaultODataBatchHandler.ParseBatchRequestsAsync(HttpContext context)
   at Microsoft.AspNet.OData.Batch.DefaultODataBatchHandler.ProcessBatchAsync(HttpContext context, RequestDelegate nextHandler)
   at Microsoft.AspNet.OData.Batch.ODataBatchMiddleware.Invoke(HttpContext context)
   at Microsoft.AspNetCore.Authorization.AuthorizationMiddleware.Invoke(HttpContext context)
   at Microsoft.AspNetCore.Diagnostics.DeveloperExceptionPageMiddleware.Invoke(HttpContext context)

Additional detail

From the protocol, The value of dependsOn is an array of strings whose values MUST be values of either id or atomicityGroup of preceding request objects; forward references are not allowed. If a request depends on another request that is part of a different atomicity group, the atomicity group MUST be listed in dependsOn.
https://docs.oasis-open.org/odata/odata-json-format/v4.01/odata-json-format-v4.01.html#sec_BatchRequest

Referencing across changesets was introduced in Odata v4.01 https://docs.oasis-open.org/odata/new-in-odata/v4.01/cn04/new-in-odata-v4.01-cn04.html#_Toc21700029

@gathogojr gathogojr added this to To do in OData project via automation Jun 30, 2020
@KenitoInc KenitoInc changed the title Enable atomicityGroup as a dependsOn value in Odata BatchReader and BatchWriter Fix bug on atomicityGroup as a dependsOn value in Odata v4 Jul 2, 2020
@KenitoInc
Copy link
Contributor Author

PR Merged

OData project automation moved this from To do to Done Aug 13, 2020
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
OData project
  
Done
Development

No branches or pull requests

2 participants