FHIR Chat · GCP: Managing Resource Contention with FHIR Bundle · implementers

Stream: implementers

Topic: GCP: Managing Resource Contention with FHIR Bundle


view this post on Zulip Nguyen Quang Huy (Aug 06 2020 at 08:52):

Hi, so currently I am trying to update multiple FHIR resources via executeBundle[1] and "Managing Resource Contention"[2] by using Etag with If-Match header. But GCP returning "412 Precondition Failed" with "diagnostics": "the version id doesn't match current value".
But it return "200 OK" when I try to update a single FHIR resource separately via executeBundle.
The different here are:

  • Case 1: request bundle have 2 or more entries, each entry is a different resource of the same type with different versionId.
  • Case 2: request bundle have only 1 entry.

[1] https://cloud.google.com/healthcare/docs/reference/rest/v1/projects.locations.datasets.fhirStores.fhir/executeBundle
[2] http://hl7.org/fhir/http.html#concurrency

So my request body for executeBundle look like this:
POST https://healthcare.googleapis.com/v1/projects/*/locations/*/datasets/*/fhirStores/*/fhir

  • Case 1:
{
  "entry": [
    {
      "resource": {
        "active": false,
        "gender": "female",
        "id": "example1",
        "meta": {
          "lastUpdated": "2020-08-06T08:19:13.138829+00:00",
          "versionId": "validVersionIdExample1"
        },
        "resourceType": "Patient"
      },
      "request": {
        "method": "PUT",
        "url": "Patient/example1",
        "ifMatch": "W/\"validVersionIdExample1\""
      }
    },
    {
      "resource": {
        "active": false,
        "gender": "male",
        "id": "example2",
        "meta": {
          "lastUpdated": "2020-08-06T08:19:30.331322+00:00",
          "versionId": "validVersionIdExample2"
        },
        "resourceType": "Patient"
      },
      "request": {
        "method": "PUT",
        "url": "Patient/example2",
        "ifMatch": "W/\"validVersionIdExample2\""
      }
    }
  ],
  "type": "transaction",
  "resourceType": "Bundle"
}

GCP will return: "Status: 412 Precondition Failed"

{
  "issue": [
    {
      "code": "structure",
      "details": {
        "text": "invalid_headers"
      },
      "diagnostics": "the version id doesn't match current value",
      "severity": "error"
    }
  ],
  "resourceType": "OperationOutcome"
}
  • Case 2:
{
  "entry": [
    {
      "resource": {
        "active": false,
        "gender": "female",
        "id": "example1",
        "meta": {
          "lastUpdated": "2020-08-06T08:19:13.138829+00:00",
          "versionId": "validVersionIdExample1"
        },
        "resourceType": "Patient"
      },
      "request": {
        "method": "PUT",
        "url": "Patient/example1",
        "ifMatch": "W/\"validVersionIdExample1\""
      }
    }
  ],
  "type": "transaction",
  "resourceType": "Bundle"
}

GCP will return: "Status: 200 OK"

{
  "entry": [
    {
      "response": {
        "etag": "W/\"newVersionId\"",
        "lastModified": "2020-08-06T08:41:01.385494+00:00",
        "location": "https://healthcare.googleapis.com/v1/projects/*/locations/*/datasets/*/fhirStores/*/fhir/Patient/example1/_history/newVersionId",
        "status": "200 OK"
      }
    }
  ],
  "resourceType": "Bundle",
  "type": "transaction-response"
}

view this post on Zulip Lloyd McKenzie (Aug 06 2020 at 14:40):

@Paul Church

view this post on Zulip Paul Church (Aug 06 2020 at 17:14):

What are your expectations in each of these cases? It depends on the current state of the resources compared to the version IDs specified in If-Match.

view this post on Zulip Nguyen Quang Huy (Aug 07 2020 at 06:13):

Paul Church said:

What are your expectations in each of these cases? It depends on the current state of the resources compared to the version IDs specified in If-Match.

For case 1: I expect GCP to return Status: 200 OK response bundle with 2 entries which is updated resources from request. And of course those 2 resources should be updated.
For case 2: It is already return what I expect it to be returned.

view this post on Zulip Paul Church (Aug 10 2020 at 21:27):

I believe the confusion here is that the meta.lastUpdated and meta.versionId in the resources in the bundle have no effect. These fields are assigned by the server. The ifMatch header compares against the version ID of the resource currently in the store.

Also, our implementation does not check IfMatch when doing a PUT to a resource that does not exist - perhaps it is a matter of interpretation whether this should be rejected.

Your examples are succeeding or failing depending on the state of the store.

view this post on Zulip Nguyen Quang Huy (Aug 11 2020 at 08:29):

I think you miss understanding of my example. Let's me make it more clear:

  • I have 2 Patient resources which already exist in FHIR store for example are Patient/example1 & Patient/example2.
  • I send to GCP an executeBundle to PUT those 2 already exist Patients, the transaction bundle in request body will have 2 entries which is corresponding to Patient/example1 & Patient/example2.
  • The ifMatch will point to current version ID of Patient/example1 & Patient/example2 corresponding are currentVersionOfPatientExample1 & currentVersionOfPatientExample2. So it will look like this:
  "entry": [
    {
      "resource": {
        "id": "example1",
        "resourceType": "Patient"
      },
      "request": {
        "method": "PUT",
        "url": "Patient/example1",
        "ifMatch": "W/\"currentVersionOfPatientExample1\""
      }
    },
    {
      "resource": {
        "id": "example2",
        "resourceType": "Patient"
      },
      "request": {
        "method": "PUT",
        "url": "Patient/example2",
        "ifMatch": "W/\"currentVersionOfPatientExample2\""
      }
    }
  ],
  "type": "transaction",
  "resourceType": "Bundle"
}

This will sometimes succeed and sometimes fail. So I don't know what is happening here as why sometimes it succeed and sometimes it fail.

view this post on Zulip Paul Church (Aug 18 2020 at 18:56):

@Nguyen Quang Huy I haven't reproduced this so far but we're still investigating. There are no existing known issues with IfMatch that would explain it.

view this post on Zulip Paul Church (Aug 20 2020 at 15:40):

@Nguyen Quang Huy We have identified the cause of this issue and a fix is in progress. The issue is specific to transaction bundles containing more than one entry with an IfMatch condition. I don't have any workarounds to suggest but we are confident that the fix will address the issue once rolled out to production.


Last updated: Apr 12 2022 at 19:14 UTC