Tag: answer

  • Question: How to use fhir-path-cli?

    In IBM FHIR Server 4.7.0, the IBM FHIR Server team introduced fhir-path-cli and related to a blog on $everything.

    Now, let’s download some sample data on the server using the Integration Test data.

    1. Download the Sample Data
    curl -L https://raw.githubusercontent.com/IBM/FHIR/main/fhir-server-test/src/test/resources/testdata/everything-operation/Antonia30_Acosta403.json -o Antonia30_Acosta403.json
    
    1. Load the Sample Data bundle to the IBM FHIR Server
    curl -k --location --request POST 'https://localhost:9443/fhir-server/api/v4' \
    --header 'Content-Type: application/fhir+json' \
    --header "Authorization: Basic ${DUMMY_PASSWORD}" \
    --data-binary  "@Antonia30_Acosta403.json" -o response.json
    
    1. Scan the response.json for any status that is not "status": "201". For example, the status is in the family of User Request Error or Server Side Error.

    2. Check the response.json and find the id for Patient (it should be the first one).

            {
                "response": {
                    "id": "178f4a3f869-6abfe1e6-3a4a-4c9a-81a8-fb8c6263e003",
                    "status": "201",
                    "location": "Patient/178f4a3f869-6abfe1e6-3a4a-4c9a-81a8-fb8c6263e003/_history/1",
                    "etag": "W/\"1\"",
                    "lastModified": "2021-04-21T13:34:50.207684Z"
                }
            },
    
    1. Check the Patient/[id]/$everything with a _type constraint and _since.
    • Request *
    curl -k --location --request GET 'https://localhost:9443/fhir-server/api/v4/Patient/178f4a3f869-6abfe1e6-3a4a-4c9a-81a8-fb8c6263e003/$everything?_type=CarePlan,CareTeam&_since=2021-01-01T00:00:00Z&_count=1' \
        --header 'Content-Type: application/fhir+json' \
        --header "Authorization: Basic ${DUMMY_PASSWORD}" -o care.json
    
    • Response *
    {
        "resourceType": "Bundle",
        "id": "689856f9-6ef6-4d74-8f77-a813ff7b1c6d",
        "type": "searchset",
        "total": 11,
        "entry": [
            {
                "fullUrl": "https://localhost:9443/fhir-server/api/v4/Patient/178f4a3f869-6abfe1e6-3a4a-4c9a-81a8-fb8c6263e003",
                "resource": {
                    "resourceType": "Patient",
                    "id": "178f4a3f869-6abfe1e6-3a4a-4c9a-81a8-fb8c6263e003",
                    "meta": {
                        "versionId": "1",
                        "lastUpdated": "2021-04-21T13:34:50.207684Z"
                    }
                    ...
                }
            }
        ]
    }
    

    You’ll see further down CareTeam and CarePlan resources…

    1. This is where we can have a bit of fun… download the fhir-path-cli
    curl -L https://github.com/IBM/FHIR/releases/download/4.7.0/fhir-path-4.7.0-cli.jar -o fhir-path-4.7.0-cli.jar
    
    1. Let’s run the fhir-path-4.7.0-cli.jar and test a FHIRPath.

    Command Line

    java -jar fhir-path-4.7.0-cli.jar --path 'entry.fullUrl' --file care.json 
    

    Output

    https://localhost:9443/fhir-server/api/v4/Patient/178f4a3f869-6abfe1e6-3a4a-4c9a-81a8-fb8c6263e003
    https://localhost:9443/fhir-server/api/v4/Patient/178f4a3f869-6abfe1e6-3a4a-4c9a-81a8-fb8c6263e003/CarePlan/178f4a3f86a-1a9a1d73-4d1d-46d5-8494-339dddbfe9d2
    https://localhost:9443/fhir-server/api/v4/Patient/178f4a3f869-6abfe1e6-3a4a-4c9a-81a8-fb8c6263e003/CarePlan/178f4a3f86b-06c07a6c-3be7-4e6a-abb2-040ff67c8c1f
    https://localhost:9443/fhir-server/api/v4/Patient/178f4a3f869-6abfe1e6-3a4a-4c9a-81a8-fb8c6263e003/CarePlan/178f4a3f873-d8069835-938e-45b1-9a70-5aba3794f6f3
    https://localhost:9443/fhir-server/api/v4/Patient/178f4a3f869-6abfe1e6-3a4a-4c9a-81a8-fb8c6263e003/CarePlan/178f4a3f87c-ce204596-8037-416c-b2e0-fc7442d9a276
    https://localhost:9443/fhir-server/api/v4/Patient/178f4a3f869-6abfe1e6-3a4a-4c9a-81a8-fb8c6263e003/CarePlan/178f4a3f87c-46785bc7-807a-40e0-bc08-792977ac8ec8
    https://localhost:9443/fhir-server/api/v4/Patient/178f4a3f869-6abfe1e6-3a4a-4c9a-81a8-fb8c6263e003/CareTeam/178f4a3f86a-b79251c3-5019-426e-8211-748adbdfdf54
    https://localhost:9443/fhir-server/api/v4/Patient/178f4a3f869-6abfe1e6-3a4a-4c9a-81a8-fb8c6263e003/CareTeam/178f4a3f86b-22a7baab-77b3-4fb5-b318-9249ea80ec85
    https://localhost:9443/fhir-server/api/v4/Patient/178f4a3f869-6abfe1e6-3a4a-4c9a-81a8-fb8c6263e003/CareTeam/178f4a3f873-e370fba2-f45e-4cdd-b13b-781e249f84f8
    https://localhost:9443/fhir-server/api/v4/Patient/178f4a3f869-6abfe1e6-3a4a-4c9a-81a8-fb8c6263e003/CareTeam/178f4a3f87c-596d80cc-7b42-4054-bc02-a48acfcc95b7
    https://localhost:9443/fhir-server/api/v4/Patient/178f4a3f869-6abfe1e6-3a4a-4c9a-81a8-fb8c6263e003/CareTeam/178f4a3f87c-6cc197cd-b665-46e0-ad35-c016edeaf13b
    

    You’ve seen a brief introduction to fhir-operation-everything and a bonus fhir-path-cli showing the output.

    Note, DUMMY_PASSWORD should be replaced with or set as a value when the corresponding curl steps are executed.

    Thanks to my colleague that implemented $everything.

  • Question: How to use IBM FHIR Server Notifications with IBM Cloud Functions?

    A question I had recently was “How to use IBM FHIR Server” with IBM Cloud Functions….

    Here is the recipe:

    1 – Create a topic FHIR_NOTIFICATION (for instance in EventStreams)

    2 – Setup a IBM Cloud Function per https://github.com/IBM/ibm-cloud-functions-message-hub-trigger

    3 – Update your process-message with the following code:

    function main(params) {
      return new Promise((resolve, reject) => {
          console.log(params.messages);
        if (!params.messages || !params.messages[0] || !params.messages[0].value) {
          reject("Invalid arguments. Must include 'messages' JSON array with 'value' field");
        }
        const msgs = params.messages;
        const locations = [];
        for (let i = 0; i < msgs.length; i++) {
          const msg = msgs[i];
          console.log(msg.value.location);
          locations.push(msg.value.location);
        }
        resolve({
          locations,
        });
      });
    }
    
    exports.main = main;
    
    

    exports.main = main;

    4 – Invoke with parameters

        {
          "messages": [
            {
              "key": null,
              "offset": 0,
              "partition": 2,
              "topic": "FHIR_NOTIFICATION",
              "value": {
                "datasourceId": "default",
                "lastUpdated": "2021-04-16T13:55:13.312415Z",
                "location": "SearchParameter/178daf6d720-d2da7624-1664-4e50-a4f8-e558ab667fac/_history/1",
                "operationType": "create",
                "resource": {
                  "base": [
                    "Encounter"
                  ],
                  "code": "diff-start-end-time",
                  "description": "Example of sophisiticated extraction",
                  "expression": "iif(period.start.exists() and period.end.exists(), between(period.start , period.end, 'days'), {})",
                  "id": "178daf6d720-d2da7624-1664-4e50-a4f8-e558ab667fac",
                  "meta": {
                    "lastUpdated": "2021-04-16T13:55:13.312415Z",
                    "versionId": "1"
                  },
                  "name": "Example of sophisiticated extraction",
                  "resourceType": "SearchParameter",
                  "status": "draft",
                  "type": "quantity",
                  "url": "https://fhir.ibm.com/demo/diff-start-end-time"
                },
                "resourceId": "178daf6d720-d2da7624-1664-4e50-a4f8-e558ab667fac",
                "tenantId": "default"
              }
            }
          ]
        }
    

    4 – Click Invoke

    5 – Look to the Right to see the logging/activation (Expand the tick on the right-middle of the screen)

    6 – You’ll see you now have a Function connected with EventStreams.

    Notes

    The activation dashboard is important https://cloud.ibm.com/functions/dashboard. You can see great detail on the logs and what is passed to the Function.

    {
      "activationId": "960f129da9f04f138f129da9f0ef13f7",
      "annotations": [
        {
          "key": "path",
          "value": "14d753c7-8620-4caa-b6af-3934e33ae451/fhir-event-streams/process-message"
        },
        {
          "key": "waitTime",
          "value": 274
        },
        {
          "key": "kind",
          "value": "nodejs:12"
        },
        {
          "key": "timeout",
          "value": false
        },
        {
          "key": "limits",
          "value": {
            "concurrency": 1,
            "logs": 10,
            "memory": 256,
            "timeout": 60000
          }
        },
        {
          "key": "initTime",
          "value": 25
        }
      ],
      "duration": 32,
      "end": 1618583048738,
      "logs": [
        "2021-04-16T14:24:08.737951Z    stdout: [",
        "2021-04-16T14:24:08.737997Z    stdout: {",
        "2021-04-16T14:24:08.738031Z    stdout: key: null,",
        "2021-04-16T14:24:08.738037Z    stdout: offset: 0,",
        "2021-04-16T14:24:08.738042Z    stdout: partition: 2,",
        "2021-04-16T14:24:08.738047Z    stdout: topic: 'FHIR_NOTIFICATION',",
        "2021-04-16T14:24:08.738052Z    stdout: value: {",
        "2021-04-16T14:24:08.738057Z    stdout: datasourceId: 'default',",
        "2021-04-16T14:24:08.738062Z    stdout: lastUpdated: '2021-04-16T13:55:13.312415Z',",
        "2021-04-16T14:24:08.738066Z    stdout: location: 'SearchParameter/178daf6d720-d2da7624-1664-4e50-a4f8-e558ab667fac/_history/1',",
        "2021-04-16T14:24:08.738071Z    stdout: operationType: 'create',",
        "2021-04-16T14:24:08.738076Z    stdout: resource: [Object],",
        "2021-04-16T14:24:08.738081Z    stdout: resourceId: '178daf6d720-d2da7624-1664-4e50-a4f8-e558ab667fac',",
        "2021-04-16T14:24:08.738085Z    stdout: tenantId: 'default'",
        "2021-04-16T14:24:08.738134Z    stdout: }",
        "2021-04-16T14:24:08.738141Z    stdout: }",
        "2021-04-16T14:24:08.738146Z    stdout: ]",
        "2021-04-16T14:24:08.738152Z    stdout: SearchParameter/178daf6d720-d2da7624-1664-4e50-a4f8-e558ab667fac/_history/1"
      ],
      "name": "process-message",
      "namespace": "14d753c7-8620-4caa-b6af-3934e33ae451",
      "publish": false,
      "response": {
        "result": {
          "msgs": [
            {
              "key": null,
              "offset": 0,
              "partition": 2,
              "topic": "FHIR_NOTIFICATION",
              "value": {
                "datasourceId": "default",
                "lastUpdated": "2021-04-16T13:55:13.312415Z",
                "location": "SearchParameter/178daf6d720-d2da7624-1664-4e50-a4f8-e558ab667fac/_history/1",
                "operationType": "create",
                "resource": {
                  "base": [
                    "Encounter"
                  ],
                  "code": "diff-start-end-time",
                  "description": "Example of sophisiticated extraction",
                  "expression": "iif(period.start.exists() and period.end.exists(), between(period.start , period.end, 'days'), {})",
                  "id": "178daf6d720-d2da7624-1664-4e50-a4f8-e558ab667fac",
                  "meta": {
                    "lastUpdated": "2021-04-16T13:55:13.312415Z",
                    "versionId": "1"
                  },
                  "name": "Example of sophisiticated extraction",
                  "resourceType": "SearchParameter",
                  "status": "draft",
                  "type": "quantity",
                  "url": "https://fhir.ibm.com/demo/diff-start-end-time"
                },
                "resourceId": "178daf6d720-d2da7624-1664-4e50-a4f8-e558ab667fac",
                "tenantId": "default"
              }
            }
          ]
        },
        "size": 877,
        "status": "success",
        "success": true
      },
      "start": 1618583048706,
      "subject": "pb",
      "version": "0.0.1"
    }
    
  • Question: How do I decode the Job Id from the Bulk Data Export or Import on the IBM FHIR Server?

    Question: How do I decode the Job Id from the Bulk Data Export or Import on the IBM FHIR Server?

    You can use the following code to walk through and decode your job id using your passowrd.

  • Question: How do I configure fhir-notification Kafka so I don’t have to use a keystore?

    The IBM FHIR Server provides an eventing service that notifies about persistence events – CUD (Create-Update-Delete). The notification service can trigger specific actions in a downstream application. You can configure these events to flow to Apache Kafka.

    If you want to configure the IBM FHIR Server without a keystore, you can configure SASL_SSL like the below (notice there is no keystore specified).

    {
        "fhirServer":{
            "notifications":{
                "kafka": {
                    "enabled": true,
                    "topicName": "FHIR_NOTIFICATIONS",
                    "connectionProperties": {
                        "bootstrap.servers": "broker-1.mybroker.com:9093,broker-2.mybroker.com:9093,broker-0.mybroker.com:9093,broker-5.mybroker.com:9093,broker-4.mybroker.com:9093,broker-3.mybroker.com:9093",
                        "security.protocol": "SASL_SSL",
                        "sasl.mechanism": "PLAIN",
                        "ssl.protocol": "TLSv1.2",
                        "ssl.enabled.protocols": "TLSv1.2",
                        "ssl.endpoint.identification.algorithm": "HTTPS",
                        "security.inter.broker.protocol": "SSL",
                        "sasl.jaas.config": "org.apache.kafka.common.security.plain.PlainLoginModule required username=\"token\" password=\"MYPASSWORD\";",
                        "acks": "all",
                        "retries": "60",
                        "request.timeout.ms": "10000",
                        "max.block.ms": "60000",
                        "max.in.flight.requests.per.connection": "5",
                        "client.dns.lookup": "use_all_dns_ips"
                    }
                }
            }
        }
    }
    

    If you run a workload against IBM FHIR Server, it’ll generate a set of notifications…

    1. Download Kafka from https://kafka.apache.org

    2. Create a client-ssl.properties

    cat << EOF > client-ssl.properties
    bootstrap.servers=broker-2.mybroker.com:9093,broker-5.mybroker.com:9093,broker-0.mybroker.com:9093,broker-3.mybroker.com:9093,broker-4.mybroker.com:9093,broker-1.mybroker.com:9093
    sasl.jaas.config=org.apache.kafka.common.security.plain.PlainLoginModule required username="token" password="MYPASSWORD";
    sasl.mechanism=PLAIN
    security.protocol=SASL_SSL
    ssl.protocol=TLSv1.2
    EOF
    
    1. Unzip the kafka archive

    2. Check the Kafka Console Consumer

    bash bin/kafka-console-consumer.sh --bootstrap-server broker-4.mybroker.com:9093,broker-5.mybroker.com:9093,broker-3.mybroker.com:9093,broker-2.mybroker.com:9093,broker-1.mybroker.com:9093,broker-0.mybroker.com:9093 --topic FHIR_NOTIFICATION --max-messages 25 --property print.timestamp=true --consumer.config client-ssl.properties