Skip to content

Data storage and content synchronization FHIR server option

Bas van den Heuvel edited this page Oct 1, 2020 · 3 revisions

Data storage and content synchronization

Context

Applications use and generate data during a launch in the form of FHIR resources. The different applications connected to a FHIRcast session should be able to indicate that a resource has been created, updated, deleted. When required the application should be able to access the changed resource.

The main starting points of this proposal are:

  • FHIRcast allows different application to remain in context.

  • These applications generate data in the form of FHIR resources.

  • Other applications should be notified when data has been generated/changed/deleted.

  • All application should be able to access the data related to the context.

Important considerations are:

  • Prevent race conditions in which multiple applications change the same resource at the same time.

  • Reuse existing specifications when available and applicable.

The approach taken in this proposal is to reuse the FHIR defined mechanisms for reading, updating, creation and deletion of resources. So all applications retrieve the data from a FHIR repository that is linked in some way to the current login session as is illustrated in the figure below.

94823002 9f5cbc80 0403 11eb 8e3b ddd1ae0b4209

The figure shows a set of applications whose context is syncrhonized using the subpub API provided by FHIRcast. The FHIRcast hub also hosts a FHIRserver that is used by the applications to read, store, update and delete data using the FHIR restfull interface.

The POST/PUT triggers the event.

This FHIRserver can be an (in memory) instance storing only data exchanged in the topic or the FHIR server used by the hospital. Which choice is made does not impact this specification.

In order to prevent race conditions on updating resources, applications SHOULD (SHALL?) include the "If-Match" header (see https://www.hl7.org/fhir/http.html#concurrency) when making a PUT call that will override an existing resource.

Terminology

This section introduces some import concepts used in the sections below.

Context vs Content

The two main concepts related to content storage are:

  • Context → what the user is working on (Patient, Encounter, ImagingStudy, DiagnisticReport, …​)

  • Content → what is resources are generated/updated related to the context (container)

Storage Containers

Content is related to a a container. A container is defined as:

  • those events linked to a “anchor” resource type, e.g. Patient, Encounter, ImagingStudy, DiagnosticReport.

The resource in scope is defined as:

  • the currently open resource of the type.

A resource is in the container if:

  • it is the resource in scope

  • referred to from the resource in scope

  • refers to the resource in scope

Elaborations

Aspects/elaborations that were important when making the design were:

  • We want to prevent sending events large context fields between applications.

  • The system should be robust against application crashes – application crashes shall not result in data loss. HL7 currently already has an infrastructure for storage, retrieval of FHIR resources.

Dynamics

The figure below illustrates how the dynamic behavior of the proposal.

94823002 9f5cbc80 0403 11eb 8e3b ddd1ae0b4209

When a resource is updated or created in the FHIR store, the FHIR server signals to the hub that data is changed. The hub will then send an change or update event. This event is different from a Subscription. The event signals that an Content item within the current Context has changed.

A resource is in context when it falls within the container of the anchor resource. This differentiates it from events that can be received using Subscriptions. Applications can use Subscriptions in addition to the FHIRcast mechanism.

Possibly special SubscriptionTopic’s can be defined instead To Be Discussed

Event types

The specification defines the following event types:

  1. context-change: list the references of the resource that are created/changed/updated in this topic (form to be discussed).

  2. context-update: list the transaction-bundle holding the resources that are created/changed/updated in this topic.-

  3. <resourcetype>-change: as above but limited to the Container of the current resource of the resourceType

  4. <resourcetype>-update: as above but limited to the Container of the current resource of the resourceType

[resourcetype]-change

These events are send when a resource in the container of the resource in scope is changed. When the context is changed, and there are any open resoruces in the new container, an [resourcetype]-change event is send with the current context. The event contains all change events in the container that occured since the user logged-in.

Replace with Bundle with references as specified in the R5 Subscription update (http://build.fhir.org/branches/argonaut-subscription/subscription.html#payloads). Include version specific references as a recommendation

Events of this type will have the following context elements:

Key

Optionality

multiplicity

FHIR operation to generate context

Description

[resourcetype]

REQUIRED

1

[resourcetype]/{id}?_elements=identifier

provenance

The following restrictions apply:
  1. The target field SHALL include a list of all changed resources.

  2. The references in the target field SHOULD be version specific.

  3. The activity field SHALL contain one entry from "http://terminology.hl7.org/CodeSystem/v3-DataOperation".

An example of a context change event is depicted below.

{
  "timestamp": "2020-09-22T11:42:05.14",
  "id": "asldkj3902fkjefdsfds",
  "event": {
    "hub.topic": "fdb2f928-5546-4f52-87a0-0648e9ded065",
    "hub.event": "diagnosticreport-change",
    "context": [
    {
      "key": "diagnosticreport",
      "resource": {
        "resourceType": "DiagnosticReport",
        "id": "34090ifdvd09fud89",
        "identifier": [ {
            "system": "http://example.org/CodeSystem/4032940",
            "value": "somereport",
        }
        ]
      }
    },
    {
      "key": "provenance",
      "resource": {
        "resourceType": "Provenance",
        "target": [
            "reference": "Observation/90af90udfsda/_history/1"
        ],
        "recorded": "2020-09-22T11:42:01.14",
        "activity": [
            "coding": [{
                "system":"http://terminology.hl7.org/CodeSystem/v3-DataOperation"
                "value": "CREATE"
                "display": "create"
            }
            ]
        ]
      }
    },
    {
        "key": "provenance",
        "resource": {
            "resourceType": "Provenance",
            "target": [
                "reference": "DiagnosticReport/34090ifdvd09fud89/_history/2"
            ],
            "recorded": "2020-09-22T11:42:01.14",
            "activity": [
                "coding": [{
                    "system":"http://terminology.hl7.org/CodeSystem/v3-DataOperation"
                    "value": "UPDATE"
                    "display": "update"
                }
                ]
            ]
        }
    }
  }]
  }
}

[resourcetype]-update

These events are send when a resource in the container of the resource in scope is changed. When the context is changed, and there are any open resoruces in the new container, an [resourcetype]-change event is send with the current context. The event contains all change events in the container that occured since the user logged-in.

Events of this type will have the following context elements:

Key

Optionality

multiplicity

FHIR operation to generate context

Description

[resourcetype]

REQUIRED

1

[resourcetype]/{id}?_elements=identifier

bundle

Alternatively the full-resource subscription-notification Bundle from the R5 Subscription update can be used instead of Provenances (http://build.fhir.org/branches/argonaut-subscription/subscription.html#payloads)

An example of such event is depicted below:

{
  "timestamp": "2020-09-22T11:42:05.14",
  "id": "asldkj3902fkjefdsfds",
  "event": {
    "hub.topic": "fdb2f928-5546-4f52-87a0-0648e9ded065",
    "hub.event": "diagnosticreport-update",
    "context": [
      {
        "key": "diagnosticreport",
        "resource": {
          "resourceType": "DiagnosticReport",
          "id": "34090ifdvd09fud89",
          "identifier": [ {
              "system": "http://example.org/CodeSystem/4032940",
              "value": "somereport",
          }
          ]
        }
      },
      {
        "key": "bundle",
        "resource": {
          "resourceType": "Bundle"
          TBD
        }
      }
    ]
  }
}

The bundle field will be populated with a FHIR transaction Bundle.

Decision log

Storage approach

The main goal is to store content in context and to signal applications when this content is changed.

Options include: Send all information every time, store centrally, store in FHIR server

Send all information every time - can become very large messages, especially when Media are involved.

Store in central server - this an be done but should not be mandated.

Store in topic related server - this is the minimum that is required. Can be the same as the general FHIR server but does not have to. It is the FHIR endpoint that was used to discover the hub and topic.

Subscriptions are to be used for one-to-one events

Decision: Store the data in a topic related FHIR server, meaning that all content is accessible through this endpoint.

Container

Prevent all information shared every time, login session may be open for a long time, aggregating a lot of data. Smaller containers are required. Container based events are needed. Containers are scoped to the currently selected resource of the type.

Decision: Send events in container related events.

Bundles or references

Specify both events, the hub decides which one to support.

Reference event format

Different options:

  1. list of references

  2. Provenance resource

  3. List of AuditEvent Resources.

Requirements: 1. what resources has been touched 2. what operation was used (CRUD)

Both Provenance and AuditEvent are not created for this purpose. Provenance seams to be intended to group resources in order to provide a digital signature. AuditEvents are used to implement a audit log. Both will create a lot of dupplication when used in this context. Also the activity they report on is slightly different from the CRUD operation performed.

Another option would be a batch Bundle where each bundle entry contains the request that resulted in the resource. Excuting the request will result in response Bundle that contains the most recent version of the resources touched.

Composition does not allow storage of the operation, just what resources have been touched.

Provenance is promising as the purpose states: 'The Provenance resource corresponds to a single activity that identifies a set of resources (target) generated by the activity.'. Which corresponds to the purpose at hand; a list of resources that have been generated in activity (context).

The other alternative would be to code the changes directly in the context, as a set of repeating references direct.

There is no clear winner here, in line with other FHIR-cast event we will use Provenance.

That leaves open whether to use on or multiple provenance resources. Multiple allows the exact operation to be specified in the activity field. A single instance groups them all together and reduces overhead but removes the acitvity performed information.

Decision: references to changed resources are communicted using the Provenance resource, one resource per change.

To be revisited in HL7 discussions - subscription-notification would be a good alternative

Scope of events, when to start

What content is included in a update event? Only those resources changed after the open or all changed in this context. As a user may change achor resource, only including those after the open is not sufficient. An alternative could be to include those since the first open. This would exclude resources changed before, which makes sense.

This would mean that when the anchor resource is closed, older resources would be excluded. This might cause issues when the change event is used for all resources to check. This should not be the case. It is an indication of change, not of status. As the update event holds all, the reuslt of this might be that that content would not be shared anymore. That is not something that we want.

If this is to be mitigated, the best alternative would be to include all since the login.

Decision: Include those resources in the update events that were changed after the login.

Does this also apply to change event? Consistency would be to do the same.

Decision: Include those resources in the change events that were changed after the login.

Prevent race conditions on updating resources

When two applications change the resource at the same time, the update of one of the applications maybe overridden by the second. In FHIR this can be prevented by using the mechanism defined in the "Managing Resource Contention" (https://www.hl7.org/fhir/http.html#concurrency) section in FHIR.

This behavior should be recommended for FHIRcast.