diff --git a/README.md b/README.md index ebd790f..dc985c8 100644 --- a/README.md +++ b/README.md @@ -65,3 +65,77 @@ The certificates are loaded into the `certs` volume, which can be mounted in any - Hapi JPA Servers (https://github.com/hapifhir/hapi-fhir-jpaserver-starter) + +## HIE Testing Guide + +### 1. Setup +Determine whether you're running a domain-based or port-based setup. Based on this, either use the `docker-compose.yml` file for domain-based, or the `docker-compose.local.yml` file for port-based. + +This decision determines how services will be reached, and what environment needs to be used for testing. In each case, the traffic is routed through the `nginx` container, which distributes the traffic correctly based on domains or ports. See the `nginx` configuration in the corresponding `docker-compose.yml` file, and the configurations in `./configs/nginx`. + +These instructions will assume a port-based approach when giving examples, so you can swap in the corresponding domain-based urls from the `nginx.conf` files. +### 2. Verify access to OpenHIM + +Make sure console is up and running, and pointed to the correct, external (non-docker) url for the `openhim-core` api (port `8080`): +```sh +docker logs -n 100 openhim-console +``` + +Make sure `openhim-core` is running correctly: +```sh +docker logs -n 100 openhim-core +``` + +Open openhim console url in browser window: +`https://localhost` + +Log in using default password: +`root@openmrs.org/openhim-password` + +Set new admin password + +Browse the OpenHIM Dashboard +### 3. Activate and Verify the Mediators + +Go to `Mediators` tab in OpenHIM console. + +Verify that the following three mediators are registered and have active (green) heartbeats: +- OpenCR +- SHR +- FHIR-HL7 Converter + +Add the channels associated with each mediator with the green `+` button. + +Go to the `Clients and Roles` tab and create the following roles and channel assignments: +1. shr-client (all SHR mediator channels) +2. opencr-client (all OpenCR mediator channels) +3. converter-client (all Fhir Converter mediator channels) +4. mfl-client (placeholder) +5. omang-client (placeholder) +6. bd-client (placeholder) + +In the clients section, create the following clients and assign roles: +1. pims-test(shr-client, opencr-client, mfl-client) +2. ipms-test(shr-client) +3. shr(opencr-client, converter-client, mfl-client, omang-client, bd-client) +4. opencr(converter-client, omang-client, bd-client) + +For each client, add Basic Auth authentication in the Authentication tab. The client name will be the username for BasicAuth, and will need to be set correctly in configurations for the communication workflows to work. For production, certificate-based authentication will be used. + +To enable testing, the following temporary client should also be created and given access to all of the listed roles: `postman/postman`. If a password other than this default is required, the corresponding settings need to be updated in each `.json` file in `.postman/collections` for the tests to run correctly. + + + +### 4. Run Postman Tests + + + +### MLLP Testing +Dependencies: openhim-core, openhim-console, shr, fhir-converter + +1. Check that the + +1. ADT +2. ORU + +For this test, the test will respond with success if it passes, and it will log a couple transactions in the OpenHIM console. \ No newline at end of file diff --git a/configs/nginx/certs/apache-selfsigned.crt b/configs/nginx/certs/apache-selfsigned.crt new file mode 100644 index 0000000..f3aa38c --- /dev/null +++ b/configs/nginx/certs/apache-selfsigned.crt @@ -0,0 +1,23 @@ +-----BEGIN CERTIFICATE----- +MIID6TCCAtGgAwIBAgIUaGXsC4IYiywkFsJ89o6OUX+QwS0wDQYJKoZIhvcNAQEL +BQAwgYMxCzAJBgNVBAYTAlVTMQswCQYDVQQIDAJXQTESMBAGA1UEBwwJU2hvcmVs +aW5lMRIwEAYDVQQKDAlJLVRFQ0gtVVcxDTALBgNVBAsMBERJR0kxEjAQBgNVBAMM +CWxvY2FsaG9zdDEcMBoGCSqGSIb3DQEJARYNcG1hbmtvQHV3LmVkdTAeFw0yMTEw +MjgyMTE3MzlaFw0yMjEwMjgyMTE3MzlaMIGDMQswCQYDVQQGEwJVUzELMAkGA1UE +CAwCV0ExEjAQBgNVBAcMCVNob3JlbGluZTESMBAGA1UECgwJSS1URUNILVVXMQ0w +CwYDVQQLDARESUdJMRIwEAYDVQQDDAlsb2NhbGhvc3QxHDAaBgkqhkiG9w0BCQEW +DXBtYW5rb0B1dy5lZHUwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQDW +ClsP30SnLNv0iE+DUgV3Np7Dy648B3cCFYkZag4HDdDj0DIqzho+bpuxwph641Sc +TzZhu45FssDr8hUMPVMJJsuz3k+y1BhjlLP0fiN/wrxA+9qjEZXvezSLbGd6iaAY +cvP46a7rklaekJELMXRFb8FcPoQ1y+0U/WnzgPy5p/e9jCOJN5zWTNs8XXyXs2/I +aw33pV0LSdPp9cwSiiDEGwg0i+11+I+nO28HVR70tGW5oX830TtH6/XFVqXVVs9P +RMi6aI0i6G0vT+r1C28b0uRzBjHRQ7mWRHUeAFZIfLQBceIEfAeIah5c6Cbrgg+O ++IlmfghNOHXv49vEx8tvAgMBAAGjUzBRMB0GA1UdDgQWBBSBMLMDRU6yGYk8a1Dz +SlDjdUV3CTAfBgNVHSMEGDAWgBSBMLMDRU6yGYk8a1DzSlDjdUV3CTAPBgNVHRMB +Af8EBTADAQH/MA0GCSqGSIb3DQEBCwUAA4IBAQCHeK1EBQ17HeRwKs2meUZOyGvk +vtuHDdjDkFU/uoD9Kb4SihK7cQb8eAdLo+veQKKt7Q5GR4/7+6eqFunbczLC/W1A +WlkeaSxyzNtWvEf2Jik51+VQ+1zcTjZGc0ON6ajl9hvFnLXo19DYcCvxVlL09Aci +KyBsYkO08nQhKPcMIPQCn1aq30TJ3EfquKPiqbtVkod9Dvyld1oNrLZqvSe8EHnn +Ak7nE135l68ZTesyveL5IG6AJeNgjESldcsV0S+1TJ3Et9kNpFZgL/S7XK/8FbGY +VvUK7Kb3wwVPuG1RmZ3zroQ8DhFm9C9cO8W/XUns5g1kQpdMUIIkIwSKDmIp +-----END CERTIFICATE----- diff --git a/configs/nginx/certs/apache-selfsigned.key b/configs/nginx/certs/apache-selfsigned.key new file mode 100644 index 0000000..af1eec0 --- /dev/null +++ b/configs/nginx/certs/apache-selfsigned.key @@ -0,0 +1,28 @@ +-----BEGIN PRIVATE KEY----- +MIIEvwIBADANBgkqhkiG9w0BAQEFAASCBKkwggSlAgEAAoIBAQDWClsP30SnLNv0 +iE+DUgV3Np7Dy648B3cCFYkZag4HDdDj0DIqzho+bpuxwph641ScTzZhu45FssDr +8hUMPVMJJsuz3k+y1BhjlLP0fiN/wrxA+9qjEZXvezSLbGd6iaAYcvP46a7rklae +kJELMXRFb8FcPoQ1y+0U/WnzgPy5p/e9jCOJN5zWTNs8XXyXs2/Iaw33pV0LSdPp +9cwSiiDEGwg0i+11+I+nO28HVR70tGW5oX830TtH6/XFVqXVVs9PRMi6aI0i6G0v +T+r1C28b0uRzBjHRQ7mWRHUeAFZIfLQBceIEfAeIah5c6Cbrgg+O+IlmfghNOHXv +49vEx8tvAgMBAAECggEBAL6YHhp2H/YVdg+7ycIQKZnMY3fKSW5e31RVxO2CiNcz +ME2MOP/w42GwsKeLtqfHArLlvnEsyDW8RRpVSPTLLsO5bi7OyX1ebBFQeyY9pHLB +/0yGeFw47qB/v3xfnY16O7tJsYJ25DIU71jnNqEW+ohSSYZQjP4yhvzn447XzzOp +giY6e8zbuhTkGVYYKPY19t2S6PMtY5ehZs43VRt2Mt3xIvBoXDwaLEglR+5y+P0m +Ox3qR5H/0iUqNBWDcHzlg+9rXL2frujkV5hC2RHaaeUpfiSt24F27JI1s2MurMG8 +DtFxmUWeLC73se5WDPKHfvXGBRT3NrmMdfiXv3QZcOECgYEA/fMPCkFsS/TqaCYs +sKMZ+/iDM8TGRsJeUgmlGUvP+44UO7ljKASSq7iDkWW5qPQsrdUOcE++zz6Jo2y9 +p8GqIsCkmalyNj5DQkJtFATj/FpuaZ2QsjELm/U8Jdot0ErAAuDttsDUSrPCfxll +/D/xaZQiq+Mutev7pyuY1nFEAjkCgYEA18TM+xFQMbkmGJr8zPr3Ae9cAqKVAnPR +U1N5histXYttWPjZvMOV8xUzTr+SxxgpEcItLLMru5S/nyQks1xfBEmQeE10Bnks +haYVIcE+rDJsXsRQ0OWq9ba13hD0JvkcIrpE1JhQARDA2b9NOx4pYyWi/kBFUAry +E+NVrimwGucCgYEAkoKSIMaR5liMjD3J9raCnT5I46sZAWXN6OKrn6Z/fZAA2Fwi +esn4nJ29OjtIG9OTm06aH+3CFersmZ545Ln0oEwoKob535WYVDfimnQf3E2H+eLv +wf5NxlJ7uxLe75bQpFiEjLU/RUHkalOK5Tc23kSapDRTlJ1q+I1MhhuesvECgYAk +mPDbtPgRNwJLMh6m9fpnjZ3hpIn5vINIyuPV6gTr1PZbHPpxlgsdC/+D3+KZenOc +236mEk3cp0JJT+wZsBU9uOyUOy7u2ia/FIiJDSoAMx1Gha3fgNUakD8Qx3diFOa8 +zTNXi+4mAB110Yjb+iWy93NKBMS86t5cmTazL8b7CQKBgQD49cg8Ep8WiA2W0z3z +ZRGwhqLu1d6hv55VmV2T4WyqxTzCi54bjMN9Ft13jXBCTLQHFyWpn8doA8WxyJ4f +57DWmaf5nfqjifKm+CY91nLa+oyyqUx2sM49Hd4/ZEscpg60eK0PKRKnJEKkW1k7 +6cBwtXl1YajNVglvpA91Kobomw== +-----END PRIVATE KEY----- diff --git a/configs/nginx/nginx.local.conf b/configs/nginx/nginx.local.conf new file mode 100644 index 0000000..99f7c4d --- /dev/null +++ b/configs/nginx/nginx.local.conf @@ -0,0 +1,128 @@ +events { + worker_connections 4096; +} + +http { + fastcgi_read_timeout 1d; + client_max_body_size 1024M; + proxy_read_timeout 1d; + + ssl_certificate /etc/certs/apache-selfsigned.crt; + ssl_certificate_key /etc/certs/apache-selfsigned.key; + + ssl_protocols TLSv1 TLSv1.1 TLSv1.2; + ssl_ciphers HIGH:!aNULL:!MD5; + + server { + listen 443 ssl; + server_name _; + + location / { + resolver 127.0.0.11 valid=30s; + proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; + proxy_set_header X-Forwarded-Proto $scheme; + proxy_set_header Host $http_host; + proxy_redirect off; + + set $upstream openhim-console; + proxy_pass http://$upstream; + } + } + + server { + listen 8080 ssl; + server_name _; + + location / { + resolver 127.0.0.11 valid=30s; + proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; + proxy_set_header X-Forwarded-Proto $scheme; + proxy_set_header Host $http_host; + proxy_redirect off; + + set $upstream openhim-core; + proxy_pass https://$upstream:8080; + } + } + + server { + listen 5001 default_server; + server_name _; + + location / { + resolver 127.0.0.11 valid=30s; + proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; + proxy_set_header X-Forwarded-Proto $scheme; + proxy_set_header Host $http_host; + proxy_redirect off; + + set $upstream openhim-core; + proxy_pass http://$upstream:5001; + } + } + server { + listen 5000 ssl; + server_name _; + + location / { + resolver 127.0.0.11 valid=30s; + proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; + proxy_set_header X-Forwarded-Proto $scheme; + proxy_set_header Host $http_host; + proxy_redirect off; + + set $upstream openhim-core; + proxy_pass https://$upstream:5000; + } + } + + # Mediators + + server { + listen 10040 ssl; + + location / { + resolver 127.0.0.11 valid=30s; + proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; + proxy_set_header X-Forwarded-Proto $scheme; + proxy_set_header Host $http_host; + proxy_redirect off; + + set $upstream mllp; + proxy_pass http://$upstream:2527; + } + } + + server { + listen 2019 ssl; + + location / { + resolver 127.0.0.11 valid=30s; + proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; + proxy_set_header X-Forwarded-Proto $scheme; + proxy_set_header Host $http_host; + proxy_redirect off; + + set $upstream fhir-converter; + proxy_pass http://$upstream:2019; + } + } + + server { + listen 8090 ssl; + server_name _; + + location / { + resolver 127.0.0.11 valid=30s; + proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; + proxy_set_header X-Forwarded-Proto $scheme; + proxy_set_header Host $http_host; + proxy_redirect off; + + set $upstream shr-fhir; + proxy_pass http://$upstream:8080; + } + } + + # Testing +} \ No newline at end of file diff --git a/configs/nginx/nginx.ports.conf b/configs/nginx/nginx.ports.conf index 9f5b7c0..208c2bc 100644 --- a/configs/nginx/nginx.ports.conf +++ b/configs/nginx/nginx.ports.conf @@ -6,23 +6,10 @@ http { fastcgi_read_timeout 1d; client_max_body_size 1024M; proxy_read_timeout 1d; - - # # Redirect to use https - # server { - # listen 80 default_server; - - # server_name _; - - # return 301 https://$host$request_uri; - # } server { listen 80 default_server; server_name _; - # server_name moh.org.bw; - - # ssl_certificate /etc/letsencrypt/fullchain2.pem; - # ssl_certificate_key /etc/letsencrypt/privkey2.pem; ssl_protocols TLSv1 TLSv1.1 TLSv1.2; ssl_ciphers HIGH:!aNULL:!MD5; @@ -33,7 +20,9 @@ http { proxy_set_header X-Forwarded-Proto $scheme; proxy_set_header Host $http_host; proxy_redirect off; - proxy_pass http://openhim-console; + + set $upstream openhim-console; + proxy_pass http://$upstream; } } @@ -47,7 +36,9 @@ http { proxy_set_header X-Forwarded-Proto $scheme; proxy_set_header Host $http_host; proxy_redirect off; - proxy_pass https://openhim-core:8080; + + set $upstream openhim-core; + proxy_pass https://$upstream:8080; } } @@ -60,7 +51,9 @@ http { proxy_set_header X-Forwarded-Proto $scheme; proxy_set_header Host $http_host; proxy_redirect off; - proxy_pass http://mllp:2575; + + set $upstream mllp; + proxy_pass http://$upstream:2527; } } @@ -74,11 +67,14 @@ http { proxy_set_header X-Forwarded-Proto $scheme; proxy_set_header Host $http_host; proxy_redirect off; - proxy_pass http://openhim-core:5001; + + set $upstream openhim-core; + proxy_pass http://$upstream:5001; } } + server { - listen 5000 default_server; + listen 5000 ssl; server_name _; location / { @@ -87,194 +83,26 @@ http { proxy_set_header X-Forwarded-Proto $scheme; proxy_set_header Host $http_host; proxy_redirect off; - proxy_pass https://openhim-core:5000; + + set $upstream openhim-core; + proxy_pass https://$upstream:5000; } } - # server { - # listen 443 ssl; - # server_name core.moh.org.bw; - - # ssl_certificate /etc/letsencrypt/fullchain2.pem; - # ssl_certificate_key /etc/letsencrypt/privkey2.pem; - - # ssl_protocols TLSv1 TLSv1.1 TLSv1.2; - # ssl_ciphers HIGH:!aNULL:!MD5; - - # location / { - # resolver 127.0.0.11 valid=30s; - # proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; - # proxy_set_header X-Forwarded-Proto $scheme; - # proxy_set_header Host $http_host; - # proxy_redirect off; - # proxy_pass https://openhim-core:8080; - # } - # } - - # server { - # listen 443 ssl; - # server_name openhim.moh.org.bw; - - # ssl_certificate /etc/letsencrypt/fullchain2.pem; - # ssl_certificate_key /etc/letsencrypt/privkey2.pem; - - # ssl_protocols TLSv1 TLSv1.1 TLSv1.2; - # ssl_ciphers HIGH:!aNULL:!MD5; - - # location / { - # resolver 127.0.0.11 valid=30s; - # proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; - # proxy_set_header X-Forwarded-Proto $scheme; - # proxy_set_header Host $http_host; - # proxy_redirect off; - # proxy_pass https://openhim-core:5000; - # } - # } - - # server { - # listen 443 ssl; - # server_name opencr-fhir.moh.org.bw; - - # ssl_certificate /etc/letsencrypt/fullchain2.pem; - # ssl_certificate_key /etc/letsencrypt/privkey2.pem; - - # ssl_protocols TLSv1 TLSv1.1 TLSv1.2; - # ssl_ciphers HIGH:!aNULL:!MD5; - - # location / { - # resolver 127.0.0.11 valid=30s; - # proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; - # proxy_set_header X-Forwarded-Proto $scheme; - # proxy_set_header Host $http_host; - # proxy_redirect off; - # proxy_pass http://opencr-fhir:8080; - # } - # } - - # server { - # listen 443 ssl; - # server_name shr-fhir.moh.org.bw; - - # ssl_certificate /etc/letsencrypt/fullchain2.pem; - # ssl_certificate_key /etc/letsencrypt/privkey2.pem; - - # ssl_protocols TLSv1 TLSv1.1 TLSv1.2; - # ssl_ciphers HIGH:!aNULL:!MD5; - - # location / { - # resolver 127.0.0.11 valid=30s; - # proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; - # proxy_set_header X-Forwarded-Proto $scheme; - # proxy_set_header Host $http_host; - # proxy_redirect off; - # proxy_pass http://shr-fhir:8080; - # } - # } - - - # server { - # listen 443 ssl; - # server_name es.moh.org.bw; - - # ssl_certificate /etc/letsencrypt/fullchain2.pem; - # ssl_certificate_key /etc/letsencrypt/privkey2.pem; - - # ssl_protocols TLSv1 TLSv1.1 TLSv1.2; - # ssl_ciphers HIGH:!aNULL:!MD5; - - # location / { - # resolver 127.0.0.11 valid=30s; - # proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; - # proxy_set_header X-Forwarded-Proto $scheme; - # proxy_set_header Host $http_host; - # proxy_redirect off; - # proxy_pass http://es:9200; - # } - # } - - - # server { - # listen 80; - # server_name openhim.moh.org.bw; - - # ssl_certificate /etc/letsencrypt/fullchain2.pem; - # ssl_certificate_key /etc/letsencrypt/privkey2.pem; - - # ssl_protocols TLSv1 TLSv1.1 TLSv1.2; - # ssl_ciphers HIGH:!aNULL:!MD5; - - # location / { - # resolver 127.0.0.11 valid=30s; - # proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; - # proxy_set_header X-Forwarded-Proto $scheme; - # proxy_set_header Host $http_host; - # proxy_redirect off; - # proxy_pass http://openhim-core:5001; - # } - # } - - - # # Mediators: - # server { - # listen 443 ssl; - # server_name shr.moh.org.bw; - - # ssl_certificate /etc/letsencrypt/fullchain2.pem; - # ssl_certificate_key /etc/letsencrypt/privkey2.pem; - - # ssl_protocols TLSv1 TLSv1.1 TLSv1.2; - # ssl_ciphers HIGH:!aNULL:!MD5; - - # location / { - # resolver 127.0.0.11 valid=30s; - # proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; - # proxy_set_header X-Forwarded-Proto $scheme; - # proxy_set_header Host $http_host; - # proxy_redirect off; - # set $upstream shr; - # proxy_pass http://$upstream:3000; - # } - # } - - - # server { - # listen 443 ssl; - # server_name opencr.moh.org.bw; - - # ssl_certificate /etc/letsencrypt/fullchain2.pem; - # ssl_certificate_key /etc/letsencrypt/privkey2.pem; - - # ssl_protocols TLSv1 TLSv1.1 TLSv1.2; - # ssl_ciphers HIGH:!aNULL:!MD5; - - # location / { - # resolver 127.0.0.11 valid=30s; - # proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; - # proxy_set_header X-Forwarded-Proto $scheme; - # proxy_set_header Host $http_host; - # proxy_redirect off; - # set $upstream opencr; - # proxy_pass http://$upstream:3000; - # } - # } - - # server { - # listen 443 ssl; - # server_name hl72fhir.moh.org.bw; + server { + listen 8090 ssl; + server_name _; - # ssl_certificate /etc/letsencrypt/fullchain2.pem; - # ssl_certificate_key /etc/letsencrypt/privkey2.pem; + location / { + resolver 127.0.0.11 valid=30s; + proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; + proxy_set_header X-Forwarded-Proto $scheme; + proxy_set_header Host $http_host; + proxy_redirect off; - # ssl_protocols TLSv1 TLSv1.1 TLSv1.2; - # ssl_ciphers HIGH:!aNULL:!MD5; + set $upstream shr-fhir; + proxy_pass http://$upstream:8080; + } + } - # location / { - # proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; - # proxy_set_header X-Forwarded-Proto $scheme; - # proxy_set_header Host $http_host; - # proxy_redirect off; - # set $upstream fhir-converter; - # proxy_pass http://fhir-converter:2019; - # } - # } } \ No newline at end of file diff --git a/configs/openhim-console/port.json b/configs/openhim-console/port.json index 7217d7a..73348e1 100644 --- a/configs/openhim-console/port.json +++ b/configs/openhim-console/port.json @@ -1,7 +1,7 @@ { "version": "1.10.0", "minimumCoreVersion": "3.4.0", -"protocol": "http", +"protocol": "https", "host": "localhost", "port": 8080, "title": "Local OpenHIM Console", diff --git a/configs/shr/config_ports.json b/configs/shr/config_ports.json new file mode 100644 index 0000000..63f396e --- /dev/null +++ b/configs/shr/config_ports.json @@ -0,0 +1,24 @@ +{ + "app": { + "port": 3000, + "mllpPort": 2575 + }, + "mediator": { + "api": { + "username": "root@openhim.org", + "password": "openhim", + "apiURL": "https://openhim-core:8080", + "trustSelfSigned": true, + "urn": "urn:mediator:bw_sharedhealthrecord" + }, + "client": { + "id": "shr-client", + "password": "shr-client" + } + }, + "fhirServer": { + "mpiURL": "https://openhim-core:5000/CR/fhir", + "baseURL": "https://shr-fhir:8080/fhir" + }, + "fhirConverterUrl": "https://openhim-core:5000/72f" +} diff --git a/configs/shr/mediator_ports.json b/configs/shr/mediator_ports.json new file mode 100644 index 0000000..a73d9f3 --- /dev/null +++ b/configs/shr/mediator_ports.json @@ -0,0 +1,151 @@ +{ + "urn": "urn:mediator:bw_sharedhealthrecord", + "version": "0.2.0", + "name": "BW Shared Health Record", + "description": "Botswana Shared Health Record", + "defaultChannelConfig": [ + { + "methods": [ + "GET", + "POST", + "PUT", + "PATCH" + ], + "type": "http", + "whitelist": [], + "authType": "private", + "matchContentTypes": [], + "properties": [], + "txViewAcl": [], + "txViewFullAcl": [], + "txRerunAcl": [], + "status": "enabled", + "rewriteUrls": false, + "addAutoRewriteRules": true, + "autoRetryEnabled": false, + "autoRetryPeriodMinutes": 60, + "requestBody": true, + "responseBody": true, + "name": "SHR - FHIR Passthrough", + "description": "Get or Post a new FHIR Resource to the SHR", + "urlPattern": "^/SHR/fhir.*$", + "routes": [ + { + "type": "http", + "status": "enabled", + "forwardAuthHeader": false, + "name": "SHR - Get/Create/Update Resource", + "secured": false, + "host": "shr", + "port": 3000, + "path": "", + "pathTransform": "s/SHR\\/fhir/fhir/g", + "primary": true, + "username": "", + "password": "" + } + ], + "priority": 1 + }, + { + "methods": [ + "GET", + "POST", + "PUT" + ], + "type": "http", + "whitelist": [], + "authType": "private", + "matchContentTypes": [], + "properties": [], + "txViewAcl": [], + "txViewFullAcl": [], + "txRerunAcl": [], + "status": "enabled", + "rewriteUrls": false, + "addAutoRewriteRules": true, + "autoRetryEnabled": false, + "autoRetryPeriodMinutes": 60, + "name": "SHR - Get/Update IPS", + "requestBody": true, + "responseBody": true, + "description": "Get or Update the Internaional Patient Summary Bundle from the SHR", + "urlPattern": "^/SHR/fhir/ips.*$", + "routes": [ + { + "type": "http", + "status": "enabled", + "forwardAuthHeader": false, + "name": "SHR - Get IPS", + "secured": false, + "host": "shr", + "port": 3000, + "path": "", + "pathTransform": "s/SHR\\/fhir\\/ips/ips/g", + "primary": true, + "username": "", + "password": "" + } + ], + "alerts": [], + "rewriteUrlsConfig": [], + "priority": 2 + }, + { + "methods": [ + "GET", + "POST", + "PUT" + ], + "type": "http", + "whitelist": [], + "authType": "private", + "matchContentTypes": [], + "properties": [], + "txViewAcl": [], + "txViewFullAcl": [], + "txRerunAcl": [], + "status": "enabled", + "rewriteUrls": false, + "addAutoRewriteRules": true, + "autoRetryEnabled": false, + "autoRetryPeriodMinutes": 60, + "name": "SHR - Laboratory", + "requestBody": true, + "responseBody": true, + "description": "Get or Update the Laboratory Order Bundle in the SHR", + "urlPattern": "^/SHR/fhir/ips.*$", + "routes": [ + { + "type": "http", + "status": "enabled", + "forwardAuthHeader": false, + "name": "SHR - Laboratory", + "secured": false, + "host": "shr", + "port": 3000, + "path": "", + "pathTransform": "s/SHR\\/fhir\\/ips/ips/g", + "primary": true, + "username": "", + "password": "" + } + ], + "alerts": [], + "rewriteUrlsConfig": [], + "priority": 3 + } + ], + "endpoints": [ + { + "name": "SHR Endpoint", + "host": "shr", + "path": "/", + "port": 3000, + "primary": true, + "forwardAuthHeader": false, + "status": "enabled", + "type": "http" + } + ] +} \ No newline at end of file diff --git a/dist/build_package.sh b/dist/build_package.sh index 6333bde..25e7064 100755 --- a/dist/build_package.sh +++ b/dist/build_package.sh @@ -1,10 +1,7 @@ #!/bin/bash -# Save codebase as tarball -git archive --output=./dist/package/hie-botswana.tar --format=tar HEAD - # Pull latest images -docker-compose --profile core --profile mediator --profile test pull +docker-compose -f docker-compose.local.yml pull # Save images to .tar files docker save --output ./dist/package/docker/nginx.tar nginx:latest @@ -23,3 +20,5 @@ docker save --output ./dist/package/docker/opencr.tar intrahealth/opencr:latest docker save --output ./dist/package/docker/httpbin.tar kennethreitz/httpbin:latest docker save --output ./dist/package/docker/mllp-http.tar rivethealth/mllp-http:latest docker save --output ./dist/package/docker/newman.tar postman/newman:latest + +docker save --output ./dist/package/docker/mllp-tester.tar ghcr.io/b-techbw/mllp-tester:latest diff --git a/dist/load_package.sh b/dist/load_package.sh index 0ad53a5..3646c68 100755 --- a/dist/load_package.sh +++ b/dist/load_package.sh @@ -1,4 +1,2 @@ #!/bin/bash -tar -xvf ./package/hie-botswana.tar -C ~/ - -ls -1 ./package/docker/*.tar | xargs --no-run-if-empty -L 1 docker load -i \ No newline at end of file +ls -1 ./dist/package/docker/*.tar | xargs --no-run-if-empty -L 1 docker load -i \ No newline at end of file diff --git a/docker-compose.ci.yml b/docker-compose.ci.yml index 5af69ff..d4da399 100644 --- a/docker-compose.ci.yml +++ b/docker-compose.ci.yml @@ -77,7 +77,7 @@ services: profiles: ["mediators"] container_name: shr hostname: shr - image: ghcr.io/i-tech-uw/shared-health-record:main + image: ghcr.io/i-tech-uw/shared-health-record:v0.3.3 restart: unless-stopped environment: - NODE_ENV=docker diff --git a/docker-compose.local.yml b/docker-compose.local.yml new file mode 100644 index 0000000..435c282 --- /dev/null +++ b/docker-compose.local.yml @@ -0,0 +1,224 @@ +version: '2.4' + +## Port Assignments: +## See .env file + +## Container debugging: +# 1. append the following lines to desired container +# 2. boot up the container using `docker-compose up -d` +# 3 run `docker exec -it bash` to start interactive shell +# +# tty: true +# stdin_open: true +# entrypoint: bash + +services: + ### + # nginx reverse proxy + # TODO: set up to use non-root user. See https://www.rockyourcode.com/run-docker-nginx-as-non-root-user/ + # TODO: Run letsencrypt as docker container: https://hub.docker.com/r/certbot/certbot/ + ### + nginx: + image: nginx:latest + container_name: nginx + hostname: nginx + restart: unless-stopped + ports: + - 80:80 + - 443:443 + - 8080:8080 + - 8090:8090 + - 5000:5000 + - 5001:5001 + # - 2019:2019 + - 10040:10040 + - 10060:10060 + volumes: + - ./configs/nginx/nginx.local.conf:/etc/nginx/nginx.conf + - nginx-data:/var/www + - ./configs/nginx/certs:/etc/certs + networks: + - hie + logging: + options: + max-size: "10k" + max-file: "3" + + ### + # OpenCR + ### + opencr: + container_name: opencr + hostname: opencr + image: intrahealth/opencr:latest + restart: unless-stopped + environment: + - NODE_ENV=docker + - HAPI_FHIR_URL=http://opencr-fhir:8080/fhir/metadata + networks: + - hie + volumes: + - ./configs/opencr/config_port.json:/src/server/config/config_docker.json + - ./configs/opencr/mediator_port.json:/src/server/config/mediator.json + + opencr-fhir: + image: hapiproject/hapi:latest + container_name: opencr-fhir + hostname: opencr-fhir + restart: unless-stopped + networks: + - hie + healthcheck: + test: "curl -sS http://opencr-fhir:8080/fhir/metadata || exit 1" + interval: 90s + timeout: 30s + retries: 3 + volumes: + - cr-data:/data/hapi + + opencr-es: + container_name: es + image: intrahealth/elasticsearch:latest + restart: unless-stopped + environment: + - node.name=es01 + - discovery.type=single-node + - bootstrap.memory_lock=true + - "ES_JAVA_OPTS=-Xms512m -Xmx512m" + ulimits: + memlock: + soft: -1 + hard: -1 + volumes: + - es:/usr/share/elasticsearch/data + networks: + - hie + + ### + # SHR + ### + shr: + container_name: shr + hostname: shr + image: ghcr.io/i-tech-uw/shared-health-record:v0.3.3 + restart: unless-stopped + environment: + - NODE_ENV=docker + networks: + - hie + volumes: + - ./configs/shr/config_ports.json:/app/config/config_docker.json + - ./configs/shr/mediator_ports.json:/app/config/mediator_docker.json + + shr-fhir: + image: hapiproject/hapi:latest + container_name: shr-fhir + hostname: shr-fhir + restart: unless-stopped + volumes: + - shr-data:/data/hapi + networks: + - hie + healthcheck: + test: "curl -sS http://shr-fhir:8080/fhir/metadata || exit 1" + interval: 30s + timeout: 30s + retries: 3 + + ### + # OpenHIM + ### + openhim-core: + container_name: openhim-core + hostname: openhim-core + image: jembi/openhim-core:latest + restart: unless-stopped + environment: + mongo_url: "mongodb://mongo-db/openhim" + mongo_atnaUrl: "mongodb://mongo-db/openhim" + NODE_ENV: "development" + healthcheck: + test: "curl -sSk https://openhim-core:8080/heartbeat || exit 1" + interval: 30s + timeout: 30s + retries: 3 + networks: + - hie + + openhim-console: + container_name: openhim-console + hostname: openhim-console + image: jembi/openhim-console:latest + restart: unless-stopped + volumes: + - ./configs/openhim-console/port.json:/usr/share/nginx/html/config/default.json + healthcheck: + test: "curl -sS http://openhim-console || exit 1" + interval: 30s + timeout: 30s + retries: 3 + networks: + - hie + + mongo-db: + container_name: mongo-db + image: mongo:3.4 + volumes: + - "mongo-data:/data/db" + restart: unless-stopped + networks: + - hie + + fhir-converter: + container_name: fhir-converter + hostname: fhir-converter + restart: unless-stopped + image: ghcr.io/b-techbw/openhim-mediator-fhir-converter:latest + volumes: + - ./configs/fhir-converter/config_port.json:/app/config.json + - /app/src/service-templates + networks: + - hie + + httpbin: + image: kennethreitz/httpbin:latest + container_name: httpbin + hostname: httpbin + networks: + - hie + + # Newman Tests + newman: + image: postman/newman + volumes: + - ./.postman:/.postman + entrypoint: newman run $POSTMAN_COLLECTION -e /.postman/postman_env.ci.json --insecure --timeout-request 20000 --delay-request 500 + networks: + - hie + + mllp_tests: + container_name: mllp_tests + image: ghcr.io/b-techbw/mllp-tester:main + networks: + - hie + volumes: + - ./test/mllp:/test + tty: true + stdin_open: true + entrypoint: sh + +volumes: + es: + driver: local + mongo-data: + driver: local + sqldata: + driver: local + shr-data: + driver: local + cr-data: + driver: local + nginx-data: + driver: local +networks: + hie: diff --git a/docker-compose.yml b/docker-compose.yml index 400651a..f1a04da 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -112,7 +112,7 @@ services: profiles: ["mediator"] container_name: shr hostname: shr - image: ghcr.io/i-tech-uw/shared-health-record:v0.2.1 + image: ghcr.io/i-tech-uw/shared-health-record:v0.3.3 restart: unless-stopped environment: - NODE_ENV=docker @@ -231,11 +231,10 @@ services: mllp_tests: profiles: ["test"] container_name: mllp_tests - build: ./test + image: ghcr.io/b-techbw/mllp-tester:latest networks: - hie - volumes: - - ./test:/test + volumes: es: driver: local diff --git a/heartbeat b/heartbeat new file mode 100644 index 0000000..979be02 --- /dev/null +++ b/heartbeat @@ -0,0 +1 @@ +{"master":1411.2413046,"mediators":{"urn:mediator:hl7v2tofhir_translator":1142.0250136},"now":1635456738668} \ No newline at end of file diff --git a/test/Dockerfile b/test/Dockerfile deleted file mode 100644 index e5aaf12..0000000 --- a/test/Dockerfile +++ /dev/null @@ -1,7 +0,0 @@ -FROM debian:buster-slim - -WORKDIR /test - -RUN apt-get update && apt-get -y install socat - -ENTRYPOINT [ "/test/tests.sh" ] \ No newline at end of file diff --git a/test/mllp/messages/example-adt.hl7 b/test/mllp/messages/example-adt.hl7 new file mode 100644 index 0000000..7ec7a4f --- /dev/null +++ b/test/mllp/messages/example-adt.hl7 @@ -0,0 +1,10 @@ +MSH|^~\&|||||202109211304||ADT^A04|54200|D|2.4|||AL|NE| +EVN||202109211304|||MT^MEDITECH|202109211304| +PID|1||GG00001280^^^^MR^GGC~OMANG123^^^^SS^GGC~GG1403^^^^PI^GGC~MOH0004687^^^^HUB^GGC||Test^ADT^Message^^^^L||19790921|F|||PLOT 123^^Gaborone^B^0101||00267891608025|||S||XG0000002195| +NK1|1|Test^Test|BR^Brother|Plot 123^^Gaborone^B^0101|00267891608029||NOK| +PV1|1|O|HGGMMO|RF|||K^Naicker^Kalvin^^^^^^^^^^XX|||||||||||CLI||U|||||||||||||||||||GGC||REG|||202109211304| +PV2|||||||||||1||||||||||||||RF|||||||||||N| +ROL|1|AD|AT|K^Naicker^Kalvin^^^^^^^^^^XX| +ROL|2|AD|PP|GENPRI00^Doctor^Private^^^^^^^^^^XX| +GT1|1||Test^ADT^Message||PLOT 123^^Gaborone^B^0101|00267891608025|||||SF|OMANG123| +IN1|1|Citizens||Citizens|Botswana Government^Ministry of Health^Gaborone^B^0101| \ No newline at end of file diff --git a/test/messages/example-oru.hl7 b/test/mllp/messages/example-oru.hl7 similarity index 92% rename from test/messages/example-oru.hl7 rename to test/mllp/messages/example-oru.hl7 index f26962e..4d1411e 100644 --- a/test/messages/example-oru.hl7 +++ b/test/mllp/messages/example-oru.hl7 @@ -1,5 +1,5 @@ MSH|^~\&|LAB|GGC|||202106101550||ORU^R01|165293.1|D| -PID|1|TEST0062404|GG00042482^^^^MR^GGC~GG5714^^^^PI^GGC~TEST0062404^^^^HUB^GGC||Murambi^Tawanda||19880616|M||CT|Plot 1011^^Gaborone^Botswana^00267|||||M|| ZG0000044218|23904823048923 +PID|1|TEST0062404|GG00042482^^^^MR^GGC~GG5714^^^^PI^GGC~TEST0062404^^^^HUB^GGC||Murambi^Tawanda||19880616|M||CT|Plot 1011^^Gaborone^Botswana^00267|||||M|| ZG0000044218| OBR|1|MOH001^LAB|68222^LAB|COVID^SARS-CoV-2 PCR^L|||202106031400|||||||202106101545||ZZHGGMMO^Healthpost^Mmopane||00049731||||||LAB|F||^^^^^R| OBX|1|ST|SARS-CoV-2 PCR^SARS-CoV-2 PCR^L||INCONCLUSIVE|||N||A^S|F||||GNHL^National Health Laboratory^L| OBX|2|ST|S-Cov-2 RVW^SARS-CoV-2 PCR REVIEW^L||.|||N||A^S|F|||202106101549|GNHL^National Health Laboratory^L| diff --git a/test/mllp/tests.sh b/test/mllp/tests.sh new file mode 100755 index 0000000..cbf4cc3 --- /dev/null +++ b/test/mllp/tests.sh @@ -0,0 +1,20 @@ +#!/bin/bash +hostname="mllp-adt" + +for hl7File in messages/* +do + echo "Testing $hl7File" + lines="" + + while IFS='' read -r LINE || [ -n "${LINE}" ]; do + LINE=`echo $LINE | sed -e 's/^[[:space:]]*//'` + echo "processing line: ${LINE}" + lines="${lines}${LINE}\x0d" + done < $hl7File + + msg="\x0b${lines}\x1c\x0d" + + echo $hostname + + echo -ne $msg | socat - TCP:$hostname:2575 +done \ No newline at end of file diff --git a/test/tests.sh b/test/tests.sh deleted file mode 100755 index d4258d5..0000000 --- a/test/tests.sh +++ /dev/null @@ -1,17 +0,0 @@ -#!/bin/bash -for hl7File in messages/* -do - echo "Testing $hl7File" - msg="\x0b" - - while IFS='' read -r LINE || [ -n "${LINE}" ]; do - echo "processing line: ${LINE}" - LINE=`printf "%q" $LINE` - msg="${msg}${LINE}\x0d" - done < $hl7File - - msg="${msg}\x1c\x0d" - - echo $msg - printf $msg | socat - TCP:mllp:2575 -done \ No newline at end of file