From 17e45f3504db4cd15da793e49dae8b9104d0c8e1 Mon Sep 17 00:00:00 2001 From: bradsawadye Date: Thu, 19 Oct 2023 10:19:20 +0200 Subject: [PATCH 01/19] Add mapping for cr-candidates endpoint This will map the jempi patients into fhir format for the match endpoint in jempi TB-181 --- .../docker-compose.config.yml | 14 ++++++ .../mapping-mediator/searchMatch.json | 50 +++++++++++++++++++ .../mapping-mediator/searchMatchResponse.json | 48 ++++++++++++++++++ 3 files changed, 112 insertions(+) create mode 100644 client-registry-jempi/importer/mapping-mediator/searchMatch.json create mode 100644 client-registry-jempi/importer/mapping-mediator/searchMatchResponse.json diff --git a/client-registry-jempi/importer/mapping-mediator/docker-compose.config.yml b/client-registry-jempi/importer/mapping-mediator/docker-compose.config.yml index 7c761fdf..42de2a47 100644 --- a/client-registry-jempi/importer/mapping-mediator/docker-compose.config.yml +++ b/client-registry-jempi/importer/mapping-mediator/docker-compose.config.yml @@ -23,6 +23,10 @@ services: target: /searchAll.json - source: mediator-config-searchAllResponse.json target: /searchAllResponse.json + - source: mediator-config-searchMatch.json + target: /searchMatch.json + - source: mediator-config-searchMatchResponse.json + target: /searchMatchResponse.json networks: mapping-mediator: # This command will only attempt to import the config when the uptime responds with a 2xx @@ -69,6 +73,16 @@ configs: name: mediator-config-searchAllResponse.json-${mediator_config_searchAllResponse_json_DIGEST:?err} labels: name: jempi + mediator-config-searchMatch.json: + file: ./searchMatch.json + name: mediator-config-searchMatch.json-${mediator_config_searchMatch_json_DIGEST:?err} + labels: + name: jempi + mediator-config-searchMatchResponse.json: + file: ./searchMatchResponse.json + name: mediator-config-searchMatchResponse.json-${mediator_config_searchMatchResponse_json_DIGEST:?err} + labels: + name: jempi networks: mapping-mediator: diff --git a/client-registry-jempi/importer/mapping-mediator/searchMatch.json b/client-registry-jempi/importer/mapping-mediator/searchMatch.json new file mode 100644 index 00000000..c18739a1 --- /dev/null +++ b/client-registry-jempi/importer/mapping-mediator/searchMatch.json @@ -0,0 +1,50 @@ +{ + "name": "Search Endpoint probabilistic", + "endpoint": { + "pattern": "/fhir/Patients/match", + "method": "POST" + }, + "transformation": { + "input": "JSON", + "output": "JSON" + }, + "constants": { + "resourceType": "Bundle", + "type": "searchset" + }, + "inputTransforms": { + "total": "$count(lookupRequests.jempiSearchMatch.data.goldenRecords)", + "entry": "$map(lookupRequests.jempiSearchMatch.data.goldenRecords, function($v) {{'fullUrl': 'Patient/' & $v.goldenId, 'resource': {'resourceType': 'Patient','id': $v.goldenId,'name': {'given': [$v.demographicData.givenName],'family': $v.demographicData.familyName},'address': [{'city': $v.demographicData.city}],'birthDate': $v.demographicData.dob,'telecom': [{'value': $v.demographicData.phoneNumber,'system': 'phone'}],'identifier': [{'system': $v.sourceId.facility,'value': $v.sourceId.patient},{'system': 'NationalID','value': $v.demographicData.nationalId}],'gender': $v.demographicData.gender}}})" + }, + "inputMapping": { + "constants.resourceType": "resourceType", + "constants.type": "type", + "transforms.total": "total", + "transforms.entry": "entry" + }, + "requests": { + "lookup": [ + { + "id": "jempiSearchMatch", + "forwardExistingRequestBody": true, + "config": { + "method": "post", + "headers": { + "contentType": "application/json" + }, + "url": "http://openhim-mapping-mediator:3003/search-response-match", + "params": { + "query": { + "candidateThreshold": { + "path": "query.candidateThreshold" + } + } + } + }, + "extract": { + "JeMPIResponse": "$.body" + } + } + ] + } +} diff --git a/client-registry-jempi/importer/mapping-mediator/searchMatchResponse.json b/client-registry-jempi/importer/mapping-mediator/searchMatchResponse.json new file mode 100644 index 00000000..367cb63c --- /dev/null +++ b/client-registry-jempi/importer/mapping-mediator/searchMatchResponse.json @@ -0,0 +1,48 @@ +{ + "name": "Search Patients response probabilistic", + "endpoint": { + "pattern": "/search-response-match", + "method": "POST" + }, + "transformation": { + "input": "JSON", + "output": "JSON" + }, + "inputTransforms": { + "candidateThreshold": "$exists(query.candidateThreshold) ? query.candidateThreshold : constants.candidateThreshold", + "nationalId": "$exists(requestBody.identifier) and $exists(requestBody.identifier[0]) and $count($filter(requestBody.identifier, function($v) {$contains($v.system, 'NationalID')})) > 0 ? $filter(requestBody.identifier, function($v) {$contains($v.system, 'NationalID')})[0].value : null", + "name": "$exists(requestBody.name) and $exists(requestBody.name[0]) and $exists(requestBody.name[0].given[0]) ? requestBody.name[0].given[0] : null", + "familyName": "$exists(requestBody.name) and $exists(requestBody.name[0]) ? requestBody.name[0].family : null", + "city": "$exists(requestBody.address) and $exists(requestBody.address[0]) ? requestBody.address[0].city : null", + "phoneNumber": "$exists(requestBody.telecom) and $exists(requestBody.telecom[0]) ? requestBody.telecom[0].value : null" + }, + "inputMapping": { + "transforms.candidateThreshold": "candidateThreshold", + "transforms.nationalId": "demographicData.nationalId", + "transforms.familyName": "demographicData.familyName", + "transforms.name": "demographicData.givenName", + "requestBody.gender": "demographicData.gender", + "requestBody.birthDate": "demographicData.dob", + "transforms.city": "demographicData.city", + "transforms.phoneNumber": "demographicData.phoneNumber" + }, + "constants": { + "candidateThreshold": 0.9 + }, + "requests": { + "response": { + "id": "jempiSearchMatchResponse", + "primary": true, + "config": { + "method": "post", + "headers": { + "contentType": "application/fhir+json" + }, + "url": "http://jempi-api:50000/JeMPI/cr-candidates" + }, + "extract": { + "JeMPIResponse": "$.body" + } + } + } +} From 6a67d8c18f16a29f9d168678c36e9594f45c97b7 Mon Sep 17 00:00:00 2001 From: bradsawadye Date: Thu, 19 Oct 2023 10:23:29 +0200 Subject: [PATCH 02/19] Configure the candidate threshold by query The candidate threshold can be changed by adding the query parameter "candidateThreshold" to the request. The default value is 0.9 TB-181 --- .../importer/mapping-mediator/register-response.json | 3 ++- .../importer/mapping-mediator/register.json | 9 ++++++++- 2 files changed, 10 insertions(+), 2 deletions(-) diff --git a/client-registry-jempi/importer/mapping-mediator/register-response.json b/client-registry-jempi/importer/mapping-mediator/register-response.json index be8e5a7c..8a61597d 100644 --- a/client-registry-jempi/importer/mapping-mediator/register-response.json +++ b/client-registry-jempi/importer/mapping-mediator/register-response.json @@ -10,6 +10,7 @@ }, "inputTransforms": { "currentDate": "$now()", + "candidateThreshold": "$exists(query.candidateThreshold) ? query.candidateThreshold : constants.candidateThreshold", "sourcePatient": "$exists(requestBody.identifier) and $exists(requestBody.identifier[0]) and $exists(requestBody.identifier[0].value) ? {'patient': requestBody.identifier[0].value, 'facility': requestBody.identifier[0].system} : null", "nationalId": "$exists(requestBody.identifier) and $exists(requestBody.identifier[0]) and $count($filter(requestBody.identifier, function($v) {$contains($v.system, 'NationalID')})) > 0 ? $filter(requestBody.identifier, function($v) {$contains($v.system, 'NationalID')})[0].value : null", "name": "$exists(requestBody.name) and $exists(requestBody.name[0]) and $exists(requestBody.name[0].given[0]) ? requestBody.name[0].given[0] : null", @@ -18,7 +19,7 @@ "phoneNumber": "$exists(requestBody.telecom) and $exists(requestBody.telecom[0]) ? requestBody.telecom[0].value : null" }, "inputMapping": { - "constants.candidateThreshold": "candidateThreshold", + "transforms.candidateThreshold": "candidateThreshold", "transforms.sourcePatient": "sourceId", "transforms.nationalId": "demographicData.nationalId", "transforms.familyName": "demographicData.familyName", diff --git a/client-registry-jempi/importer/mapping-mediator/register.json b/client-registry-jempi/importer/mapping-mediator/register.json index a6f64cd8..ca6be472 100644 --- a/client-registry-jempi/importer/mapping-mediator/register.json +++ b/client-registry-jempi/importer/mapping-mediator/register.json @@ -35,7 +35,14 @@ "headers": { "contentType": "application/fhir+json" }, - "url": "http://openhim-mapping-mediator:3003/register-response" + "url": "http://openhim-mapping-mediator:3003/register-response", + "params": { + "query": { + "candidateThreshold": { + "path": "query.candidateThreshold" + } + } + } }, "extract": { "JeMPIResponse": "$.body" From b3dc03a335d93ab73b87535ae42e22a5465a354f Mon Sep 17 00:00:00 2001 From: bradsawadye Date: Thu, 19 Oct 2023 10:45:08 +0200 Subject: [PATCH 03/19] Make the names more descriptive --- client-registry-jempi/importer/mapping-mediator/searchAll.json | 2 +- .../importer/mapping-mediator/searchAllResponse.json | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/client-registry-jempi/importer/mapping-mediator/searchAll.json b/client-registry-jempi/importer/mapping-mediator/searchAll.json index 54c04047..1b833a34 100644 --- a/client-registry-jempi/importer/mapping-mediator/searchAll.json +++ b/client-registry-jempi/importer/mapping-mediator/searchAll.json @@ -1,5 +1,5 @@ { - "name": "Search Endpoint", + "name": "Search Endpoint deterministic", "endpoint": { "pattern": "/fhir/Patients", "method": "POST" diff --git a/client-registry-jempi/importer/mapping-mediator/searchAllResponse.json b/client-registry-jempi/importer/mapping-mediator/searchAllResponse.json index aa9a4bb5..96a89b2e 100644 --- a/client-registry-jempi/importer/mapping-mediator/searchAllResponse.json +++ b/client-registry-jempi/importer/mapping-mediator/searchAllResponse.json @@ -1,5 +1,5 @@ { - "name": "Search Response Endpoint", + "name": "Search Response Endpoint deterministic", "endpoint": { "pattern": "/search-response", "method": "POST" From 131e1fd11e27eda48fcea950c54a5627b0ba5190 Mon Sep 17 00:00:00 2001 From: bradsawadye Date: Tue, 24 Oct 2023 11:24:50 +0200 Subject: [PATCH 04/19] Update the documentation --- client-registry-jempi/README.md | 71 +++++++++++++++++++++++++++++++++ 1 file changed, 71 insertions(+) diff --git a/client-registry-jempi/README.md b/client-registry-jempi/README.md index 39446d7e..7fc94ac5 100644 --- a/client-registry-jempi/README.md +++ b/client-registry-jempi/README.md @@ -46,6 +46,8 @@ via the [mapping mediator](https://github.com/jembi/openhim-mediator-mapping) (i POST http://localhost:3003/fhir/Patient +The `candidateThreshold` can optionally be set in the request query. The default value is 0.9 + { "resourceType": "Patient", "gender": "male", @@ -207,3 +209,72 @@ POST http://localhost:3003/fhir/Patients ] } ``` + +## Query patients probabilistic + +via the api (in JeMPI format) + +```sh +POST - http://localhost:50000/JeMPI/cr-candidates + +{ + "candidateThreshold": 0.9, + "sourceId": { + "facility": "fac1", + "patient": "pat1" + }, + "demographicData": { + "givenName": "XXX", + "familyName": "YYY", + "gender": "female", + "dob": "20000101", + "phoneNumber": "123456789", + "city": "Cape Town", + "nationalId": "1234567890" + } +} +``` + +via the [mapping mediator](https://github.com/jembi/openhim-mediator-mapping) (in fhir format) + +```sh + +POST http://localhost:3003/fhir/Patients/match + +The `candidateThreshold` can optionally be set in the request query. The default value is 0.9 + +{ + "resourceType": "Patient", + "gender": "male", + "birthDate": "1968-04-15", + "name": [ + { + "family": "cread", + "given": [ + "Jacess" + ] + } + ], + "address": [ + { + "city": "Indianapolis" + } + ], + "identifier": [ + { + "system": "https://instantopenhie.org/client1", + "value": "6b4573e7-f9dc-49ea-9ebb-daaa6b74a534" + }, + { + "value": "60934be6-ce88-48af-958e-02d88f77eec9", + "system": "NationalID" + } + ], + "telecom": [ + { + "value": "899-882-4991", + "system": "phone" + } + ] +} +``` From 547a8d7c28507b7d3419bf909614e1ff23951454 Mon Sep 17 00:00:00 2001 From: bradsawadye Date: Thu, 26 Oct 2023 07:42:05 +0200 Subject: [PATCH 05/19] Adjust the endpoint for probabilistic patient matching The input payload has been changed to a fhir Parameter as required --- .../docker-compose.config.yml | 20 +++---- .../searchAllProbabilistic.json | 40 +++++++++++++ .../searchAllProbabilisticResponse.json | 56 +++++++++++++++++++ .../mapping-mediator/searchMatch.json | 50 ----------------- .../mapping-mediator/searchMatchResponse.json | 48 ---------------- 5 files changed, 106 insertions(+), 108 deletions(-) create mode 100644 client-registry-jempi/importer/mapping-mediator/searchAllProbabilistic.json create mode 100644 client-registry-jempi/importer/mapping-mediator/searchAllProbabilisticResponse.json delete mode 100644 client-registry-jempi/importer/mapping-mediator/searchMatch.json delete mode 100644 client-registry-jempi/importer/mapping-mediator/searchMatchResponse.json diff --git a/client-registry-jempi/importer/mapping-mediator/docker-compose.config.yml b/client-registry-jempi/importer/mapping-mediator/docker-compose.config.yml index 42de2a47..d794f28a 100644 --- a/client-registry-jempi/importer/mapping-mediator/docker-compose.config.yml +++ b/client-registry-jempi/importer/mapping-mediator/docker-compose.config.yml @@ -23,10 +23,10 @@ services: target: /searchAll.json - source: mediator-config-searchAllResponse.json target: /searchAllResponse.json - - source: mediator-config-searchMatch.json - target: /searchMatch.json - - source: mediator-config-searchMatchResponse.json - target: /searchMatchResponse.json + - source: mediator-config-searchAllProbabilistic.json + target: /searchAllProbabilistic.json + - source: mediator-config-searchAllProbabilisticResponse.json + target: /searchAllProbabilisticResponse.json networks: mapping-mediator: # This command will only attempt to import the config when the uptime responds with a 2xx @@ -73,14 +73,14 @@ configs: name: mediator-config-searchAllResponse.json-${mediator_config_searchAllResponse_json_DIGEST:?err} labels: name: jempi - mediator-config-searchMatch.json: - file: ./searchMatch.json - name: mediator-config-searchMatch.json-${mediator_config_searchMatch_json_DIGEST:?err} + mediator-config-searchAllProbabilistic.json: + file: ./searchAllProbabilistic.json + name: mediator-config-searchAllProbabilistic.json-${mediator_config_searchAllProbabilistic_json_DIGEST:?err} labels: name: jempi - mediator-config-searchMatchResponse.json: - file: ./searchMatchResponse.json - name: mediator-config-searchMatchResponse.json-${mediator_config_searchMatchResponse_json_DIGEST:?err} + mediator-config-searchAllProbabilisticResponse.json: + file: ./searchAllProbabilisticResponse.json + name: mediator-config-searchAllProbabilisticResponse.json-${mediator_config_searchAllProbabilisticResponse_json_DIGEST:?err} labels: name: jempi diff --git a/client-registry-jempi/importer/mapping-mediator/searchAllProbabilistic.json b/client-registry-jempi/importer/mapping-mediator/searchAllProbabilistic.json new file mode 100644 index 00000000..70e8e9f4 --- /dev/null +++ b/client-registry-jempi/importer/mapping-mediator/searchAllProbabilistic.json @@ -0,0 +1,40 @@ +{ + "name": "Search Endpoint probabilistic", + "endpoint": { + "pattern": "/fhir/Patients/match", + "method": "POST" + }, + "transformation": { + "input": "JSON", + "output": "JSON" + }, + "constants": { + "resourceType": "Bundle", + "type": "searchset" + }, + "inputTransforms": { + "total": "$count(lookupRequests.jempiSearchAllProbabilistic.data.goldenRecords)", + "entry": "$map(lookupRequests.jempiSearchAllProbabilistic.data.goldenRecords, function($v) {{'fullUrl': 'Patient/' & $v.goldenId, 'resource': {'resourceType': 'Patient','id': $v.goldenId,'name': {'given': [$v.demographicData.givenName],'family': $v.demographicData.familyName},'address': [{'city': $v.demographicData.city}],'birthDate': $v.demographicData.dob,'telecom': [{'value': $v.demographicData.phoneNumber,'system': 'phone'}],'identifier': [{'system': $v.sourceId.facility,'value': $v.sourceId.patient},{'system': 'NationalID','value': $v.demographicData.nationalId}],'gender': $v.demographicData.gender}}})" + }, + "inputMapping": { + "constants.resourceType": "resourceType", + "constants.type": "type", + "transforms.total": "total", + "transforms.entry": "entry" + }, + "requests": { + "lookup": [ + { + "id": "jempiSearchAllProbabilistic", + "forwardExistingRequestBody": true, + "config": { + "method": "post", + "headers": { + "contentType": "application/json" + }, + "url": "http://openhim-mapping-mediator:3003/search-response-probabilistic" + } + } + ] + } +} diff --git a/client-registry-jempi/importer/mapping-mediator/searchAllProbabilisticResponse.json b/client-registry-jempi/importer/mapping-mediator/searchAllProbabilisticResponse.json new file mode 100644 index 00000000..5d3c3662 --- /dev/null +++ b/client-registry-jempi/importer/mapping-mediator/searchAllProbabilisticResponse.json @@ -0,0 +1,56 @@ +{ + "name": "Search Response Endpoint deterministic", + "endpoint": { + "pattern": "/search-response-probabilistic", + "method": "POST" + }, + "transformation": { + "input": "JSON", + "output": "JSON" + }, + "inputValidation": { + "type": "object", + "properties": { + "requestBody": { + "type": "object", + "properties": { + "parameter": { + "type": "array", + "items": { + "type": "object", + "properties": { + "name": { + "type": "string" + }, + "valueString": { + "type": "string" + } + }, + "required": ["name", "valueString"] + }, + "minItems": 1 + } + }, + "required": ["parameter"] + } + } + }, + "inputTransforms": { + "operands": "$append([], $map(requestBody.parameter, function($v) {{'operator': $single($v.part, function($v) {$v.name = 'operator'}).valueString, 'operand': {'fn': $single($v.part, function($v) {$v.name = 'fn'}).valueString, 'distance': $single($v.part, function($v) {$v.name = 'distance'}).valueInteger, 'name': $v.name, 'value': $v.valueString}}}))" + }, + "inputMapping": { + "transforms.operands": "operands", + "transforms.operands[0].operand": "operand" + }, + "requests": { + "response": [ + { + "id": "jempiSearchAllProbabilisticResponse", + "config": { + "method": "post", + "url": "http://jempi-api:50000/JeMPI/cr-find" + } + } + ] + } +} diff --git a/client-registry-jempi/importer/mapping-mediator/searchMatch.json b/client-registry-jempi/importer/mapping-mediator/searchMatch.json deleted file mode 100644 index c18739a1..00000000 --- a/client-registry-jempi/importer/mapping-mediator/searchMatch.json +++ /dev/null @@ -1,50 +0,0 @@ -{ - "name": "Search Endpoint probabilistic", - "endpoint": { - "pattern": "/fhir/Patients/match", - "method": "POST" - }, - "transformation": { - "input": "JSON", - "output": "JSON" - }, - "constants": { - "resourceType": "Bundle", - "type": "searchset" - }, - "inputTransforms": { - "total": "$count(lookupRequests.jempiSearchMatch.data.goldenRecords)", - "entry": "$map(lookupRequests.jempiSearchMatch.data.goldenRecords, function($v) {{'fullUrl': 'Patient/' & $v.goldenId, 'resource': {'resourceType': 'Patient','id': $v.goldenId,'name': {'given': [$v.demographicData.givenName],'family': $v.demographicData.familyName},'address': [{'city': $v.demographicData.city}],'birthDate': $v.demographicData.dob,'telecom': [{'value': $v.demographicData.phoneNumber,'system': 'phone'}],'identifier': [{'system': $v.sourceId.facility,'value': $v.sourceId.patient},{'system': 'NationalID','value': $v.demographicData.nationalId}],'gender': $v.demographicData.gender}}})" - }, - "inputMapping": { - "constants.resourceType": "resourceType", - "constants.type": "type", - "transforms.total": "total", - "transforms.entry": "entry" - }, - "requests": { - "lookup": [ - { - "id": "jempiSearchMatch", - "forwardExistingRequestBody": true, - "config": { - "method": "post", - "headers": { - "contentType": "application/json" - }, - "url": "http://openhim-mapping-mediator:3003/search-response-match", - "params": { - "query": { - "candidateThreshold": { - "path": "query.candidateThreshold" - } - } - } - }, - "extract": { - "JeMPIResponse": "$.body" - } - } - ] - } -} diff --git a/client-registry-jempi/importer/mapping-mediator/searchMatchResponse.json b/client-registry-jempi/importer/mapping-mediator/searchMatchResponse.json deleted file mode 100644 index 367cb63c..00000000 --- a/client-registry-jempi/importer/mapping-mediator/searchMatchResponse.json +++ /dev/null @@ -1,48 +0,0 @@ -{ - "name": "Search Patients response probabilistic", - "endpoint": { - "pattern": "/search-response-match", - "method": "POST" - }, - "transformation": { - "input": "JSON", - "output": "JSON" - }, - "inputTransforms": { - "candidateThreshold": "$exists(query.candidateThreshold) ? query.candidateThreshold : constants.candidateThreshold", - "nationalId": "$exists(requestBody.identifier) and $exists(requestBody.identifier[0]) and $count($filter(requestBody.identifier, function($v) {$contains($v.system, 'NationalID')})) > 0 ? $filter(requestBody.identifier, function($v) {$contains($v.system, 'NationalID')})[0].value : null", - "name": "$exists(requestBody.name) and $exists(requestBody.name[0]) and $exists(requestBody.name[0].given[0]) ? requestBody.name[0].given[0] : null", - "familyName": "$exists(requestBody.name) and $exists(requestBody.name[0]) ? requestBody.name[0].family : null", - "city": "$exists(requestBody.address) and $exists(requestBody.address[0]) ? requestBody.address[0].city : null", - "phoneNumber": "$exists(requestBody.telecom) and $exists(requestBody.telecom[0]) ? requestBody.telecom[0].value : null" - }, - "inputMapping": { - "transforms.candidateThreshold": "candidateThreshold", - "transforms.nationalId": "demographicData.nationalId", - "transforms.familyName": "demographicData.familyName", - "transforms.name": "demographicData.givenName", - "requestBody.gender": "demographicData.gender", - "requestBody.birthDate": "demographicData.dob", - "transforms.city": "demographicData.city", - "transforms.phoneNumber": "demographicData.phoneNumber" - }, - "constants": { - "candidateThreshold": 0.9 - }, - "requests": { - "response": { - "id": "jempiSearchMatchResponse", - "primary": true, - "config": { - "method": "post", - "headers": { - "contentType": "application/fhir+json" - }, - "url": "http://jempi-api:50000/JeMPI/cr-candidates" - }, - "extract": { - "JeMPIResponse": "$.body" - } - } - } -} From 5c7fc033f7f091fcc790ad5ac0c801da68f5353d Mon Sep 17 00:00:00 2001 From: bradsawadye Date: Thu, 26 Oct 2023 07:44:42 +0200 Subject: [PATCH 06/19] Specify the type of error response This enables us to receive errors in fhir format --- client-registry-jempi/importer/mapping-mediator/register.json | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/client-registry-jempi/importer/mapping-mediator/register.json b/client-registry-jempi/importer/mapping-mediator/register.json index ca6be472..be153270 100644 --- a/client-registry-jempi/importer/mapping-mediator/register.json +++ b/client-registry-jempi/importer/mapping-mediator/register.json @@ -44,9 +44,7 @@ } } }, - "extract": { - "JeMPIResponse": "$.body" - } + "fhirResponse": true } ] } From f57865161c0a1917963624de4bd83db734d41deb Mon Sep 17 00:00:00 2001 From: bradsawadye Date: Thu, 26 Oct 2023 07:48:14 +0200 Subject: [PATCH 07/19] Update the documentation --- client-registry-jempi/README.md | 47 ++++++++++++--------------------- 1 file changed, 17 insertions(+), 30 deletions(-) diff --git a/client-registry-jempi/README.md b/client-registry-jempi/README.md index 7fc94ac5..a0749dbd 100644 --- a/client-registry-jempi/README.md +++ b/client-registry-jempi/README.md @@ -241,40 +241,27 @@ via the [mapping mediator](https://github.com/jembi/openhim-mediator-mapping) (i POST http://localhost:3003/fhir/Patients/match -The `candidateThreshold` can optionally be set in the request query. The default value is 0.9 - { - "resourceType": "Patient", - "gender": "male", - "birthDate": "1968-04-15", - "name": [ + "resourceType": "Parameters", + "parameter": [ { - "family": "cread", - "given": [ - "Jacess" + "name": "city", + "valueString": "Indianapeeolis", + "part": [ + { + "name": "operator", + "valueString": "and" + }, + { + "name": "fn", + "valueString": "match" + }, + { + "name": "distance", + "valueInteger": 2 + } ] } - ], - "address": [ - { - "city": "Indianapolis" - } - ], - "identifier": [ - { - "system": "https://instantopenhie.org/client1", - "value": "6b4573e7-f9dc-49ea-9ebb-daaa6b74a534" - }, - { - "value": "60934be6-ce88-48af-958e-02d88f77eec9", - "system": "NationalID" - } - ], - "telecom": [ - { - "value": "899-882-4991", - "system": "phone" - } ] } ``` From b3fecce157aa584e4d53e7318decf0eac4afb8e5 Mon Sep 17 00:00:00 2001 From: bradsawadye Date: Thu, 26 Oct 2023 07:48:49 +0200 Subject: [PATCH 08/19] Bump the version of the mapping mediator Use the version with better error handling --- openhim-mapping-mediator/docker-compose.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/openhim-mapping-mediator/docker-compose.yml b/openhim-mapping-mediator/docker-compose.yml index 9ee5054a..cdfdd87b 100644 --- a/openhim-mapping-mediator/docker-compose.yml +++ b/openhim-mapping-mediator/docker-compose.yml @@ -2,7 +2,7 @@ version: '3.9' services: openhim-mapping-mediator: - image: jembi/openhim-mediator-mapping:v3.2.1 + image: jembi/openhim-mediator-mapping:v3.3.0 environment: OPENHIM_REGISTER: ${OPENHIM_REGISTER} MONGO_URL: ${OPENHIM_MONGO_URL} From e0b7a86fcd29d2486065269087ec381133eddb48 Mon Sep 17 00:00:00 2001 From: bradsawadye Date: Thu, 26 Oct 2023 08:18:28 +0200 Subject: [PATCH 09/19] Change the pattern of the url for probabilistic matching The url now has the '$match' in it as expected --- client-registry-jempi/README.md | 20 ++++++++++++++++++- .../searchAllProbabilistic.json | 2 +- 2 files changed, 20 insertions(+), 2 deletions(-) diff --git a/client-registry-jempi/README.md b/client-registry-jempi/README.md index a0749dbd..5df0f117 100644 --- a/client-registry-jempi/README.md +++ b/client-registry-jempi/README.md @@ -239,7 +239,7 @@ via the [mapping mediator](https://github.com/jembi/openhim-mediator-mapping) (i ```sh -POST http://localhost:3003/fhir/Patients/match +POST http://localhost:3003/fhir/Patient/$match { "resourceType": "Parameters", @@ -261,6 +261,24 @@ POST http://localhost:3003/fhir/Patients/match "valueInteger": 2 } ] + }, + { + "name": "givenName", + "valueString": "drake", + "part": [ + { + "name": "operator", + "valueString": "and" + }, + { + "name": "fn", + "valueString": "match" + }, + { + "name": "distance", + "valueInteger": 2 + } + ] } ] } diff --git a/client-registry-jempi/importer/mapping-mediator/searchAllProbabilistic.json b/client-registry-jempi/importer/mapping-mediator/searchAllProbabilistic.json index 70e8e9f4..2f32a99a 100644 --- a/client-registry-jempi/importer/mapping-mediator/searchAllProbabilistic.json +++ b/client-registry-jempi/importer/mapping-mediator/searchAllProbabilistic.json @@ -1,7 +1,7 @@ { "name": "Search Endpoint probabilistic", "endpoint": { - "pattern": "/fhir/Patients/match", + "pattern": "/fhir/Patient/$match", "method": "POST" }, "transformation": { From 82fd2805595a85d2843251795d3dbe3b3ed541fa Mon Sep 17 00:00:00 2001 From: bradsawadye Date: Thu, 26 Oct 2023 08:27:35 +0200 Subject: [PATCH 10/19] Correct the probabilistic documentation --- client-registry-jempi/README.md | 39 ++++++++++++++++++--------------- 1 file changed, 21 insertions(+), 18 deletions(-) diff --git a/client-registry-jempi/README.md b/client-registry-jempi/README.md index 5df0f117..c87ee4cd 100644 --- a/client-registry-jempi/README.md +++ b/client-registry-jempi/README.md @@ -215,23 +215,26 @@ POST http://localhost:3003/fhir/Patients via the api (in JeMPI format) ```sh -POST - http://localhost:50000/JeMPI/cr-candidates +POST - http://localhost:50000/JeMPI/cr-find { - "candidateThreshold": 0.9, - "sourceId": { - "facility": "fac1", - "patient": "pat1" - }, - "demographicData": { - "givenName": "XXX", - "familyName": "YYY", - "gender": "female", - "dob": "20000101", - "phoneNumber": "123456789", - "city": "Cape Town", - "nationalId": "1234567890" + "operand": { + "fn": "match", + "name": "givenName", + "value": "drake", + "distance": 2 + }, + "operands": [ + { + "operator": "and", + "operand": { + "fn": "match", + "name": "familyName", + "value": "brake", + "distance": 2 + } } + ] } ``` @@ -245,8 +248,8 @@ POST http://localhost:3003/fhir/Patient/$match "resourceType": "Parameters", "parameter": [ { - "name": "city", - "valueString": "Indianapeeolis", + "name": "givenName", + "valueString": "drake", "part": [ { "name": "operator", @@ -263,8 +266,8 @@ POST http://localhost:3003/fhir/Patient/$match ] }, { - "name": "givenName", - "valueString": "drake", + "name": "familyName", + "valueString": "brake", "part": [ { "name": "operator", From 79c1c4248eb88dd6c5a9c275a7170c84c5c3424f Mon Sep 17 00:00:00 2001 From: bradsawadye Date: Thu, 26 Oct 2023 10:21:31 +0200 Subject: [PATCH 11/19] Respond in fhir format for lookup requests --- .../importer/mapping-mediator/searchAllProbabilistic.json | 3 ++- client-registry-jempi/importer/mapping-mediator/update.json | 4 +--- 2 files changed, 3 insertions(+), 4 deletions(-) diff --git a/client-registry-jempi/importer/mapping-mediator/searchAllProbabilistic.json b/client-registry-jempi/importer/mapping-mediator/searchAllProbabilistic.json index 2f32a99a..e1287e2e 100644 --- a/client-registry-jempi/importer/mapping-mediator/searchAllProbabilistic.json +++ b/client-registry-jempi/importer/mapping-mediator/searchAllProbabilistic.json @@ -33,7 +33,8 @@ "contentType": "application/json" }, "url": "http://openhim-mapping-mediator:3003/search-response-probabilistic" - } + }, + "fhirResponse": true } ] } diff --git a/client-registry-jempi/importer/mapping-mediator/update.json b/client-registry-jempi/importer/mapping-mediator/update.json index 3f73d486..2c18c0dd 100644 --- a/client-registry-jempi/importer/mapping-mediator/update.json +++ b/client-registry-jempi/importer/mapping-mediator/update.json @@ -37,9 +37,7 @@ }, "url": "http://openhim-mapping-mediator:3003/update-patient-response/:patientId" }, - "extract": { - "JeMPIResponse": "$.body" - } + "fhirResponse": true } ] } From a93edd564660a5e66329032435b0565a280cd9f2 Mon Sep 17 00:00:00 2001 From: bradsawadye Date: Thu, 26 Oct 2023 10:40:47 +0200 Subject: [PATCH 12/19] Add validation for input for the probabilistic matching --- .../searchAllProbabilisticResponse.json | 20 ++++++++++++++++++- 1 file changed, 19 insertions(+), 1 deletion(-) diff --git a/client-registry-jempi/importer/mapping-mediator/searchAllProbabilisticResponse.json b/client-registry-jempi/importer/mapping-mediator/searchAllProbabilisticResponse.json index 5d3c3662..98c27b6b 100644 --- a/client-registry-jempi/importer/mapping-mediator/searchAllProbabilisticResponse.json +++ b/client-registry-jempi/importer/mapping-mediator/searchAllProbabilisticResponse.json @@ -24,9 +24,27 @@ }, "valueString": { "type": "string" + }, + "part": { + "type": "array", + "items": { + "type": "object", + "properties": { + "fn": { + "type": "string" + }, + "operator": { + "type": "string" + }, + "distance": { + "type": "number" + } + }, + "required": ["fn", "distance", "operator"] + } } }, - "required": ["name", "valueString"] + "required": ["name", "valueString", "part"] }, "minItems": 1 } From 29851d2cb00f0fba2f7edd2511378461c50adf35 Mon Sep 17 00:00:00 2001 From: bradsawadye Date: Fri, 27 Oct 2023 08:36:09 +0200 Subject: [PATCH 13/19] Fix validation logic --- .../mapping-mediator/searchAllProbabilisticResponse.json | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/client-registry-jempi/importer/mapping-mediator/searchAllProbabilisticResponse.json b/client-registry-jempi/importer/mapping-mediator/searchAllProbabilisticResponse.json index 98c27b6b..3b52c67d 100644 --- a/client-registry-jempi/importer/mapping-mediator/searchAllProbabilisticResponse.json +++ b/client-registry-jempi/importer/mapping-mediator/searchAllProbabilisticResponse.json @@ -30,17 +30,17 @@ "items": { "type": "object", "properties": { - "fn": { + "name": { "type": "string" }, - "operator": { + "valueString": { "type": "string" }, - "distance": { + "valueInteger": { "type": "number" } }, - "required": ["fn", "distance", "operator"] + "required": ["name"] } } }, From 0ce21c80fd409713e5c7f7622be77a3b7655b1ae Mon Sep 17 00:00:00 2001 From: bradsawadye Date: Fri, 27 Oct 2023 08:37:19 +0200 Subject: [PATCH 14/19] Change the determinsitic endpint to a get request with the patient details being retrieved from the query --- .../importer/mapping-mediator/searchAll.json | 24 ++------ .../mapping-mediator/searchAllResponse.json | 56 ++++--------------- 2 files changed, 18 insertions(+), 62 deletions(-) diff --git a/client-registry-jempi/importer/mapping-mediator/searchAll.json b/client-registry-jempi/importer/mapping-mediator/searchAll.json index 1b833a34..af83567f 100644 --- a/client-registry-jempi/importer/mapping-mediator/searchAll.json +++ b/client-registry-jempi/importer/mapping-mediator/searchAll.json @@ -1,41 +1,29 @@ { "name": "Search Endpoint deterministic", "endpoint": { - "pattern": "/fhir/Patients", - "method": "POST" + "pattern": "/fhir/Patient/$exact", + "method": "GET" }, "transformation": { - "input": "JSON", "output": "JSON" }, - "constants": { - "resourceType": "Bundle", - "type": "searchset" - }, "inputTransforms": { - "total": "$count(lookupRequests.jempiSearchAll.data.goldenRecords)", - "entry": "$map(lookupRequests.jempiSearchAll.data.goldenRecords, function($v) {{'fullUrl': 'Patient/' & $v.goldenId, 'resource': {'resourceType': 'Patient','id': $v.goldenId,'name': {'given': [$v.demographicData.givenName],'family': $v.demographicData.familyName},'address': [{'city': $v.demographicData.city}],'birthDate': $v.demographicData.dob,'telecom': [{'value': $v.demographicData.phoneNumber,'system': 'phone'}],'identifier': [{'system': $v.sourceId.facility,'value': $v.sourceId.patient},{'system': 'NationalID','value': $v.demographicData.nationalId}],'gender': $v.demographicData.gender}}})" + "operands": "($transform := function($v) {[query.family ? {'operator': 'and', 'operand': {'fn': 'eq', 'name': 'familyName', 'value': query.family}},query.given ? {'operator': 'and', 'operand': {'fn': 'eq', 'name': 'givenName', 'value': query.given}},query.gender ? {'operator': 'and', 'operand': {'fn': 'eq', 'name': 'gender', 'value': query.gender}},query.birthDate ? {'operator': 'and', 'operand': {'fn': 'eq', 'name': 'dob', 'value': query.birthDate}},query.address ? {'operator': 'and', 'operand': {'fn': 'eq', 'name': 'city', 'value': query.address}},query.telecom ? {'operator': 'and', 'operand': {'fn': 'eq', 'name': 'phoneNumber', 'value': query.telecom}},query.identifier ? {'operator': 'and', 'operand': {'fn': 'eq', 'name': 'nationalId', 'value': query.identifier}}]};$transform(query))" }, "inputMapping": { - "constants.resourceType": "resourceType", - "constants.type": "type", - "transforms.total": "total", - "transforms.entry": "entry" + "transforms.operands": "operands", + "transforms.operands[0].operand": "operand" }, "requests": { - "lookup": [ + "response": [ { "id": "jempiSearchAll", - "forwardExistingRequestBody": true, "config": { "method": "post", "headers": { "contentType": "application/json" }, "url": "http://openhim-mapping-mediator:3003/search-response" - }, - "extract": { - "JeMPIResponse": "$.body" } } ] diff --git a/client-registry-jempi/importer/mapping-mediator/searchAllResponse.json b/client-registry-jempi/importer/mapping-mediator/searchAllResponse.json index 96a89b2e..bdebe682 100644 --- a/client-registry-jempi/importer/mapping-mediator/searchAllResponse.json +++ b/client-registry-jempi/importer/mapping-mediator/searchAllResponse.json @@ -1,5 +1,5 @@ { - "name": "Search Response Endpoint deterministic", + "name": "Search Endpoint deterministic response", "endpoint": { "pattern": "/search-response", "method": "POST" @@ -8,60 +8,28 @@ "input": "JSON", "output": "JSON" }, - "inputValidation": { - "type": "object", - "properties": { - "requestBody": { - "type": "object", - "properties": { - "parameters": { - "type": "array", - "items": { - "type": "object", - "properties": { - "name": { - "type": "string" - }, - "valueCode": { - "type": "string" - }, - "valueString": { - "type": "string" - } - }, - "required": ["name", "valueCode", "valueString"] - }, - "minItems": 1 - } - }, - "required": [ - "parameters" - ] - } - } + "constants": { + "resourceType": "Bundle", + "type": "searchset" }, "inputTransforms": { - "operands": "$append([], $map(requestBody.parameters, function($v) {{'operator': $v.name, 'operand': {'fn': 'eq', 'name': $v.valueCode, 'value': $v.valueString}}}))" - }, - "constants": { - "operator": "or", - "function": "match", - "operandFunction": "eq" + "total": "$count(lookupRequests.jempiSearchAllResponse.data.goldenRecords)", + "entry": "$map(lookupRequests.jempiSearchAllResponse.data.goldenRecords, function($v) {{'fullUrl': 'Patient/' & $v.goldenId, 'resource': {'resourceType': 'Patient','id': $v.goldenId,'name': {'given': [$v.demographicData.givenName],'family': $v.demographicData.familyName},'address': [{'city': $v.demographicData.city}],'birthDate': $v.demographicData.dob,'telecom': [{'value': $v.demographicData.phoneNumber,'system': 'phone'}],'identifier': [{'system': $v.sourceId.facility,'value': $v.sourceId.patient},{'system': 'NationalID','value': $v.demographicData.nationalId}],'gender': $v.demographicData.gender}}})" }, "inputMapping": { - "transforms.operands": "operands", - "transforms.operands[0].operand": "operand" + "constants.resourceType": "resourceType", + "constants.type": "type", + "transforms.total": "total", + "transforms.entry": "entry" }, "requests": { - "response": [ + "lookup": [ { "id": "jempiSearchAllResponse", + "forwardExistingRequestBody": true, "config": { "method": "post", "url": "http://jempi-api:50000/JeMPI/cr-find" - }, - "extract": { - "JeMPIResponse": "$.body" } } ] From afde022e690c4ec1cacb0394b332220c150f0bde Mon Sep 17 00:00:00 2001 From: bradsawadye Date: Fri, 27 Oct 2023 08:38:40 +0200 Subject: [PATCH 15/19] Update the readme Deterministic endpoint is now a get request --- client-registry-jempi/README.md | 18 ++---------------- 1 file changed, 2 insertions(+), 16 deletions(-) diff --git a/client-registry-jempi/README.md b/client-registry-jempi/README.md index c87ee4cd..0d47683a 100644 --- a/client-registry-jempi/README.md +++ b/client-registry-jempi/README.md @@ -191,23 +191,9 @@ POST http://localhost:50000/JeMPI/cr-find via the [mapping mediator](https://github.com/jembi/openhim-mediator-mapping) (in fhir format) ```sh -POST http://localhost:3003/fhir/Patients +GET http://localhost:3003/fhir/Patient/$exact -{ - "resourceType": "Parameters", - "parameters": [ - { - "name": "and", // matches to the operator (options are "and" and "or") - "valueCode": "familyName", // matches to the field name (options are "givenName", "familyName", "dob", "nationalId", "gender", "city" and "phoneNumber") - "valueString": "creexxxeead" // matches to value of the field - }, - { - "name": "and", - "valueCode": "city", - "valueString": "Indianapeeolis" - } - ] -} +Query parameters - family, given, telecom, identifier, gender, birthDate, address (city) ``` ## Query patients probabilistic From 4fb30cdac6ceb60a64646674bb02c04caaa3f9ec Mon Sep 17 00:00:00 2001 From: bradsawadye Date: Mon, 30 Oct 2023 14:26:26 +0200 Subject: [PATCH 16/19] Correct the endponits' patterns --- .../importer/mapping-mediator/register-response.json | 3 --- client-registry-jempi/importer/mapping-mediator/search.json | 2 +- client-registry-jempi/importer/mapping-mediator/searchAll.json | 2 +- .../importer/mapping-mediator/update-response.json | 3 --- client-registry-jempi/importer/mapping-mediator/update.json | 2 +- 5 files changed, 3 insertions(+), 9 deletions(-) diff --git a/client-registry-jempi/importer/mapping-mediator/register-response.json b/client-registry-jempi/importer/mapping-mediator/register-response.json index 8a61597d..76c584be 100644 --- a/client-registry-jempi/importer/mapping-mediator/register-response.json +++ b/client-registry-jempi/importer/mapping-mediator/register-response.json @@ -43,9 +43,6 @@ "contentType": "application/fhir+json" }, "url": "http://jempi-api:50000/JeMPI/cr-register" - }, - "extract": { - "JeMPIResponse": "$.body" } } } diff --git a/client-registry-jempi/importer/mapping-mediator/search.json b/client-registry-jempi/importer/mapping-mediator/search.json index 43cdd2f8..e309217b 100644 --- a/client-registry-jempi/importer/mapping-mediator/search.json +++ b/client-registry-jempi/importer/mapping-mediator/search.json @@ -2,7 +2,7 @@ "name": "Search Patient by id", "endpoint": { "pattern": "/fhir/Patient/:patientId", - "method": "POST" + "method": "GET" }, "transformation": { "input": "JSON", diff --git a/client-registry-jempi/importer/mapping-mediator/searchAll.json b/client-registry-jempi/importer/mapping-mediator/searchAll.json index af83567f..bce63d25 100644 --- a/client-registry-jempi/importer/mapping-mediator/searchAll.json +++ b/client-registry-jempi/importer/mapping-mediator/searchAll.json @@ -1,7 +1,7 @@ { "name": "Search Endpoint deterministic", "endpoint": { - "pattern": "/fhir/Patient/$exact", + "pattern": "/fhir/Patient", "method": "GET" }, "transformation": { diff --git a/client-registry-jempi/importer/mapping-mediator/update-response.json b/client-registry-jempi/importer/mapping-mediator/update-response.json index dc0101b3..dba06cba 100644 --- a/client-registry-jempi/importer/mapping-mediator/update-response.json +++ b/client-registry-jempi/importer/mapping-mediator/update-response.json @@ -37,9 +37,6 @@ "contentType": "application/json" }, "url": "http://jempi-api:50000/JeMPI/cr-update-fields" - }, - "extract": { - "JeMPIResponse": "$.body" } } } diff --git a/client-registry-jempi/importer/mapping-mediator/update.json b/client-registry-jempi/importer/mapping-mediator/update.json index 2c18c0dd..5336d3d7 100644 --- a/client-registry-jempi/importer/mapping-mediator/update.json +++ b/client-registry-jempi/importer/mapping-mediator/update.json @@ -1,7 +1,7 @@ { "name": "Update Patient", "endpoint": { - "pattern": "/fhir/update/Patient/:patientId", + "pattern": "/fhir/Patient/:patientId", "method": "PUT" }, "transformation": { From 082a5e7ff00bf663fc87a458f1e1ed3b463ae763 Mon Sep 17 00:00:00 2001 From: bradsawadye Date: Mon, 30 Oct 2023 14:36:47 +0200 Subject: [PATCH 17/19] Create openhim channel for interacting with jempi --- .../importer/openhim/openhim-import.json | 165 ++++-------------- 1 file changed, 30 insertions(+), 135 deletions(-) diff --git a/client-registry-jempi/importer/openhim/openhim-import.json b/client-registry-jempi/importer/openhim/openhim-import.json index fcde3678..7f85e189 100644 --- a/client-registry-jempi/importer/openhim/openhim-import.json +++ b/client-registry-jempi/importer/openhim/openhim-import.json @@ -1,174 +1,69 @@ { "Channels": [ { + "name": "JeMPI Patient endpoints in fhir", + "description": "JeMPI Patient endpoints in fhir format", + "urlPattern": "^/fhir/Patient.*$", "methods": [ - "POST" + "GET", + "POST", + "DELETE", + "PUT", + "OPTIONS", + "HEAD", + "TRACE", + "CONNECT", + "PATCH" ], "type": "http", - "allow": [ - "instant" - ], - "whitelist": [], - "authType": "private", - "matchContentTypes": [], - "properties": [], - "txViewAcl": [], - "txViewFullAcl": [], - "txRerunAcl": [], - "status": "enabled", - "rewriteUrls": false, - "addAutoRewriteRules": true, - "autoRetryEnabled": false, - "autoRetryPeriodMinutes": 60, - "routes": [ - { - "type": "http", - "status": "enabled", - "forwardAuthHeader": false, - "name": "JeMPI Sync Receiver", - "secured": false, - "host": "jempi-sync-receiver", - "port": 50000, - "path": "/fhir", - "pathTransform": "", - "primary": true, - "username": "", - "password": "" - } - ], + "tcpPort": null, + "tcpHost": null, + "pollingSchedule": null, "requestBody": true, "responseBody": true, - "rewriteUrlsConfig": [], - "name": "JeMPI Sync Receiver", - "urlPattern": "^/jempi/fhir.*$", - "matchContentRegex": null, - "matchContentXpath": null, - "matchContentValue": null, - "matchContentJson": null, - "pollingSchedule": null, - "tcpHost": null, - "tcpPort": null, - "updatedBy": { - "id": "638a089bed7a51001325406f", - "name": "Super User" - }, - "alerts": [] - }, - { - "methods": [ - "POST" - ], - "type": "http", "allow": [ - "instant" + "test" ], "whitelist": [], "authType": "private", - "matchContentTypes": [], - "properties": [], - "txViewAcl": [], - "txViewFullAcl": [], - "txRerunAcl": [], - "status": "enabled", - "rewriteUrls": false, - "addAutoRewriteRules": true, - "autoRetryEnabled": false, - "autoRetryPeriodMinutes": 60, "routes": [ { + "name": "Generic Mapping Mediator", "type": "http", "status": "enabled", - "forwardAuthHeader": false, - "name": "JeMPI Async Receiver", "secured": false, - "host": "jempi-async-receiver", - "port": 50000, - "path": "/fhir", + "host": "openhim-mapping-mediator", + "port": 3003, + "path": "", "pathTransform": "", "primary": true, "username": "", - "password": "" + "password": "", + "forwardAuthHeader": true, + "waitPrimaryResponse": false, + "statusCodesCheck": "2**" } ], - "requestBody": true, - "responseBody": true, - "rewriteUrlsConfig": [], - "name": "JeMPI Async Receiver", - "urlPattern": "^/jempi/async/fhir.*$", + "matchContentTypes": [], "matchContentRegex": null, "matchContentXpath": null, - "matchContentValue": null, "matchContentJson": null, - "pollingSchedule": null, - "tcpHost": null, - "tcpPort": null, - "updatedBy": { - "id": "638a089bed7a51001325406f", - "name": "Super User" - }, - "alerts": [] - }, - { - "methods": [ - "GET", - "POST", - "DELETE", - "PUT", - "OPTIONS", - "HEAD", - "TRACE", - "CONNECT", - "PATCH" - ], - "type": "http", - "allow": [ - "instant" - ], - "whitelist": [], - "authType": "private", - "matchContentTypes": [], + "matchContentValue": null, "properties": [], "txViewAcl": [], "txViewFullAcl": [], "txRerunAcl": [], + "alerts": [], "status": "enabled", "rewriteUrls": false, "addAutoRewriteRules": true, + "rewriteUrlsConfig": [], "autoRetryEnabled": false, "autoRetryPeriodMinutes": 60, - "routes": [ - { - "type": "http", - "status": "enabled", - "forwardAuthHeader": false, - "name": "JeMPI", - "secured": false, - "host": "jempi-api", - "port": 50000, - "path": "", - "pathTransform": "s/jempi\\/api\\///g", - "primary": true, - "username": "", - "password": "" - } - ], - "requestBody": true, - "responseBody": true, - "rewriteUrlsConfig": [], - "name": "JeMPI API", - "urlPattern": "^/jempi/api/.*$", - "matchContentRegex": null, - "matchContentXpath": null, - "matchContentValue": null, - "matchContentJson": null, - "pollingSchedule": null, - "tcpHost": null, - "tcpPort": null, "updatedBy": { - "id": "638a089bed7a51001325406f", + "id": "6527e7676dec203bde9f2aeb", "name": "Super User" - }, - "alerts": [] + } } ] } From b25ca6fcf9b56f1fa83916148810e5a92ff082c0 Mon Sep 17 00:00:00 2001 From: bradsawadye Date: Mon, 30 Oct 2023 14:38:37 +0200 Subject: [PATCH 18/19] Update the urls --- client-registry-jempi/README.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/client-registry-jempi/README.md b/client-registry-jempi/README.md index 0d47683a..acc247ae 100644 --- a/client-registry-jempi/README.md +++ b/client-registry-jempi/README.md @@ -124,7 +124,7 @@ PATCH - http://localhost:50000/JeMPI/cr-update-fields via the [mapping mediator](https://github.com/jembi/openhim-mediator-mapping) (in fhir format) ```sh -PUT - http://localhost:3003/fhir/update/Patient/ +PUT - http://localhost:3003/fhir/Patient/ { "resourceType": "Patient", @@ -191,7 +191,7 @@ POST http://localhost:50000/JeMPI/cr-find via the [mapping mediator](https://github.com/jembi/openhim-mediator-mapping) (in fhir format) ```sh -GET http://localhost:3003/fhir/Patient/$exact +GET http://localhost:3003/fhir/Patient Query parameters - family, given, telecom, identifier, gender, birthDate, address (city) ``` From 6abcd3ef150495b087d224122310d750bcb126cc Mon Sep 17 00:00:00 2001 From: bradsawadye Date: Mon, 30 Oct 2023 16:34:36 +0200 Subject: [PATCH 19/19] Change the search all logic so the response in not nested in an object When the request comes in via the openhim, the mapping mediator responds in an openhim response format (this is needed for all the details of the transaction to be displayed on the openhim). The logic we had before was returning the response nested in an object with the orchestrations instead of only the response body. This has been changed --- .../importer/mapping-mediator/searchAll.json | 42 ++++++++++++++++--- .../mapping-mediator/searchAllResponse.json | 18 +++----- 2 files changed, 42 insertions(+), 18 deletions(-) diff --git a/client-registry-jempi/importer/mapping-mediator/searchAll.json b/client-registry-jempi/importer/mapping-mediator/searchAll.json index bce63d25..284d56b6 100644 --- a/client-registry-jempi/importer/mapping-mediator/searchAll.json +++ b/client-registry-jempi/importer/mapping-mediator/searchAll.json @@ -8,21 +8,53 @@ "output": "JSON" }, "inputTransforms": { - "operands": "($transform := function($v) {[query.family ? {'operator': 'and', 'operand': {'fn': 'eq', 'name': 'familyName', 'value': query.family}},query.given ? {'operator': 'and', 'operand': {'fn': 'eq', 'name': 'givenName', 'value': query.given}},query.gender ? {'operator': 'and', 'operand': {'fn': 'eq', 'name': 'gender', 'value': query.gender}},query.birthDate ? {'operator': 'and', 'operand': {'fn': 'eq', 'name': 'dob', 'value': query.birthDate}},query.address ? {'operator': 'and', 'operand': {'fn': 'eq', 'name': 'city', 'value': query.address}},query.telecom ? {'operator': 'and', 'operand': {'fn': 'eq', 'name': 'phoneNumber', 'value': query.telecom}},query.identifier ? {'operator': 'and', 'operand': {'fn': 'eq', 'name': 'nationalId', 'value': query.identifier}}]};$transform(query))" + "total": "$count(lookupRequests.jempiSearchAll.data.goldenRecords)", + "entry": "$map(lookupRequests.jempiSearchAll.data.goldenRecords, function($v) {{'fullUrl': 'Patient/' & $v.goldenId, 'resource': {'resourceType': 'Patient','id': $v.goldenId,'name': {'given': [$v.demographicData.givenName],'family': $v.demographicData.familyName},'address': [{'city': $v.demographicData.city}],'birthDate': $v.demographicData.dob,'telecom': [{'value': $v.demographicData.phoneNumber,'system': 'phone'}],'identifier': [{'system': $v.sourceId.facility,'value': $v.sourceId.patient},{'system': 'NationalID','value': $v.demographicData.nationalId}],'gender': $v.demographicData.gender}}})" }, "inputMapping": { - "transforms.operands": "operands", - "transforms.operands[0].operand": "operand" + "constants.resourceType": "resourceType", + "constants.type": "type", + "transforms.total": "total", + "transforms.entry": "entry" + }, + "constants": { + "resourceType": "Bundle", + "type": "searchset" }, "requests": { - "response": [ + "lookup": [ { "id": "jempiSearchAll", "config": { - "method": "post", + "method": "get", "headers": { "contentType": "application/json" }, + "params": { + "query": { + "family": { + "path": "query.family" + }, + "given": { + "path": "query.given" + }, + "telecom": { + "path": "query.telecom" + }, + "identifier": { + "path": "query.identifier" + }, + "gender": { + "path": "query.gender" + }, + "birthDate": { + "path": "query.birthDate" + }, + "address": { + "path": "query.address" + } + } + }, "url": "http://openhim-mapping-mediator:3003/search-response" } } diff --git a/client-registry-jempi/importer/mapping-mediator/searchAllResponse.json b/client-registry-jempi/importer/mapping-mediator/searchAllResponse.json index bdebe682..59b3bece 100644 --- a/client-registry-jempi/importer/mapping-mediator/searchAllResponse.json +++ b/client-registry-jempi/importer/mapping-mediator/searchAllResponse.json @@ -2,28 +2,20 @@ "name": "Search Endpoint deterministic response", "endpoint": { "pattern": "/search-response", - "method": "POST" + "method": "GET" }, "transformation": { - "input": "JSON", "output": "JSON" }, - "constants": { - "resourceType": "Bundle", - "type": "searchset" - }, "inputTransforms": { - "total": "$count(lookupRequests.jempiSearchAllResponse.data.goldenRecords)", - "entry": "$map(lookupRequests.jempiSearchAllResponse.data.goldenRecords, function($v) {{'fullUrl': 'Patient/' & $v.goldenId, 'resource': {'resourceType': 'Patient','id': $v.goldenId,'name': {'given': [$v.demographicData.givenName],'family': $v.demographicData.familyName},'address': [{'city': $v.demographicData.city}],'birthDate': $v.demographicData.dob,'telecom': [{'value': $v.demographicData.phoneNumber,'system': 'phone'}],'identifier': [{'system': $v.sourceId.facility,'value': $v.sourceId.patient},{'system': 'NationalID','value': $v.demographicData.nationalId}],'gender': $v.demographicData.gender}}})" + "operands": "($transform := function($v) {[query.family ? {'operator': 'and', 'operand': {'fn': 'eq', 'name': 'familyName', 'value': query.family}},query.given ? {'operator': 'and', 'operand': {'fn': 'eq', 'name': 'givenName', 'value': query.given}},query.gender ? {'operator': 'and', 'operand': {'fn': 'eq', 'name': 'gender', 'value': query.gender}},query.birthDate ? {'operator': 'and', 'operand': {'fn': 'eq', 'name': 'dob', 'value': query.birthDate}},query.address ? {'operator': 'and', 'operand': {'fn': 'eq', 'name': 'city', 'value': query.address}},query.telecom ? {'operator': 'and', 'operand': {'fn': 'eq', 'name': 'phoneNumber', 'value': query.telecom}},query.identifier ? {'operator': 'and', 'operand': {'fn': 'eq', 'name': 'nationalId', 'value': query.identifier}}]};$transform(query))" }, "inputMapping": { - "constants.resourceType": "resourceType", - "constants.type": "type", - "transforms.total": "total", - "transforms.entry": "entry" + "transforms.operands": "operands", + "transforms.operands[0].operand": "operand" }, "requests": { - "lookup": [ + "response": [ { "id": "jempiSearchAllResponse", "forwardExistingRequestBody": true,