diff --git a/.github/scripts/check-referential-integrity-enforced.sh b/.github/scripts/check-referential-integrity-enforced.sh
new file mode 100755
index 000000000..39b9fd3b6
--- /dev/null
+++ b/.github/scripts/check-referential-integrity-enforced.sh
@@ -0,0 +1,10 @@
+#!/bin/bash -e
+
+ENFORCED=$(curl -s http://localhost:8080/fhir/metadata | jq -r 'isempty(.rest[].resource[].referencePolicy[] | select(. == "enforced")) | not')
+
+if [ "true" = "$ENFORCED" ]; then
+ echo "Success"
+else
+ echo "Fail"
+ exit 1
+fi
diff --git a/.github/scripts/check-referential-integrity-not-enforced.sh b/.github/scripts/check-referential-integrity-not-enforced.sh
new file mode 100755
index 000000000..f5faeee88
--- /dev/null
+++ b/.github/scripts/check-referential-integrity-not-enforced.sh
@@ -0,0 +1,10 @@
+#!/bin/bash -e
+
+ENFORCED=$(curl -s http://localhost:8080/fhir/metadata | jq -r 'isempty(.rest[].resource[].referencePolicy[] | select(. == "enforced")) | not')
+
+if [ "false" = "$ENFORCED" ]; then
+ echo "Success"
+else
+ echo "Fail"
+ exit 1
+fi
diff --git a/.github/scripts/check-total-number-of-resources.sh b/.github/scripts/check-total-number-of-resources.sh
new file mode 100755
index 000000000..a0d58ef38
--- /dev/null
+++ b/.github/scripts/check-total-number-of-resources.sh
@@ -0,0 +1,10 @@
+#!/bin/bash -e
+
+TOTAL=$(curl -s http://localhost:8080/fhir | jq -r .total)
+
+if [ "$1" = "$TOTAL" ]; then
+ echo "Success"
+else
+ echo "Fail: total number of resources was $TOTAL but should be $1"
+ exit 1
+fi
diff --git a/.github/test-data/etl/0-condition.json b/.github/test-data/etl/0-condition.json
new file mode 100644
index 000000000..a5fc02cdc
--- /dev/null
+++ b/.github/test-data/etl/0-condition.json
@@ -0,0 +1,33 @@
+{
+ "resourceType": "Bundle",
+ "type": "transaction",
+ "entry": [
+ {
+ "fullUrl": "Condition/1-1",
+ "request": {
+ "method": "PUT",
+ "url": "Condition/1-1"
+ },
+ "resource": {
+ "id": "1-1",
+ "meta": {
+ "profile": [
+ "https://fhir.bbmri.de/StructureDefinition/Condition"
+ ]
+ },
+ "resourceType": "Condition",
+ "code": {
+ "coding": [
+ {
+ "system": "http://fhir.de/CodeSystem/dimdi/icd-10-gm",
+ "code": "C34.9"
+ }
+ ]
+ },
+ "subject": {
+ "reference": "Patient/1"
+ }
+ }
+ }
+ ]
+}
diff --git a/.github/test-data/etl/1-specimen.json b/.github/test-data/etl/1-specimen.json
new file mode 100644
index 000000000..b56f203d2
--- /dev/null
+++ b/.github/test-data/etl/1-specimen.json
@@ -0,0 +1,111 @@
+{
+ "resourceType": "Bundle",
+ "type": "transaction",
+ "entry": [
+ {
+ "fullUrl": "Specimen/1-1",
+ "request": {
+ "method": "PUT",
+ "url": "Specimen/1-1"
+ },
+ "resource": {
+ "extension": [
+ {
+ "url": "https://fhir.bbmri.de/StructureDefinition/Custodian",
+ "valueReference": {
+ "reference": "Organization/zebanc"
+ }
+ }
+ ],
+ "id": "1-1",
+ "meta": {
+ "profile": [
+ "https://fhir.bbmri.de/StructureDefinition/Specimen"
+ ]
+ },
+ "resourceType": "Specimen",
+ "subject": {
+ "reference": "Patient/1"
+ },
+ "type": {
+ "coding": [
+ {
+ "code": "blood-plasma",
+ "system": "https://fhir.bbmri.de/CodeSystem/SampleMaterialType"
+ }
+ ]
+ }
+ }
+ },
+ {
+ "fullUrl": "Specimen/1-2",
+ "request": {
+ "method": "PUT",
+ "url": "Specimen/1-2"
+ },
+ "resource": {
+ "extension": [
+ {
+ "url": "https://fhir.bbmri.de/StructureDefinition/Custodian",
+ "valueReference": {
+ "reference": "Organization/zebanc"
+ }
+ }
+ ],
+ "id": "1-2",
+ "meta": {
+ "profile": [
+ "https://fhir.bbmri.de/StructureDefinition/Specimen"
+ ]
+ },
+ "resourceType": "Specimen",
+ "subject": {
+ "reference": "Patient/1"
+ },
+ "type": {
+ "coding": [
+ {
+ "code": "peripheral-blood-cells-vital",
+ "system": "https://fhir.bbmri.de/CodeSystem/SampleMaterialType"
+ }
+ ]
+ }
+ }
+ },
+ {
+ "fullUrl": "Specimen/1-3",
+ "request": {
+ "method": "PUT",
+ "url": "Specimen/1-3"
+ },
+ "resource": {
+ "extension": [
+ {
+ "url": "https://fhir.bbmri.de/StructureDefinition/Custodian",
+ "valueReference": {
+ "reference": "Organization/zebanc"
+ }
+ }
+ ],
+ "id": "1-3",
+ "meta": {
+ "profile": [
+ "https://fhir.bbmri.de/StructureDefinition/Specimen"
+ ]
+ },
+ "resourceType": "Specimen",
+ "subject": {
+ "reference": "Patient/1"
+ },
+ "type": {
+ "coding": [
+ {
+ "code": "blood-plasma",
+ "system": "https://fhir.bbmri.de/CodeSystem/SampleMaterialType"
+ }
+ ]
+ }
+ }
+ }
+ ]
+}
diff --git a/.github/test-data/etl/2-patient.json b/.github/test-data/etl/2-patient.json
new file mode 100644
index 000000000..7deebd32c
--- /dev/null
+++ b/.github/test-data/etl/2-patient.json
@@ -0,0 +1,24 @@
+{
+ "resourceType": "Bundle",
+ "type": "transaction",
+ "entry": [
+ {
+ "fullUrl": "Patient/1",
+ "request": {
+ "method": "PUT",
+ "url": "Patient/1"
+ },
+ "resource": {
+ "birthDate": "1989-11-18",
+ "gender": "male",
+ "id": "1",
+ "meta": {
+ "profile": [
+ "https://fhir.bbmri.de/StructureDefinition/Patient"
+ ]
+ },
+ "resourceType": "Patient"
+ }
+ }
+ ]
+}
diff --git a/.github/test-data/0-hospitalInformation1625911868739.json.bz2 b/.github/test-data/synthea/0-hospitalInformation1625911868739.json.bz2
similarity index 100%
rename from .github/test-data/0-hospitalInformation1625911868739.json.bz2
rename to .github/test-data/synthea/0-hospitalInformation1625911868739.json.bz2
diff --git a/.github/test-data/0-practitionerInformation1625911868739.json.bz2 b/.github/test-data/synthea/0-practitionerInformation1625911868739.json.bz2
similarity index 100%
rename from .github/test-data/0-practitionerInformation1625911868739.json.bz2
rename to .github/test-data/synthea/0-practitionerInformation1625911868739.json.bz2
diff --git a/.github/test-data/057aa36e-b892-9964-75b9-ffb46b097e34.json.bz2 b/.github/test-data/synthea/057aa36e-b892-9964-75b9-ffb46b097e34.json.bz2
similarity index 100%
rename from .github/test-data/057aa36e-b892-9964-75b9-ffb46b097e34.json.bz2
rename to .github/test-data/synthea/057aa36e-b892-9964-75b9-ffb46b097e34.json.bz2
diff --git a/.github/test-data/0696ac49-3128-87d3-7344-04510aa4f324.json.bz2 b/.github/test-data/synthea/0696ac49-3128-87d3-7344-04510aa4f324.json.bz2
similarity index 100%
rename from .github/test-data/0696ac49-3128-87d3-7344-04510aa4f324.json.bz2
rename to .github/test-data/synthea/0696ac49-3128-87d3-7344-04510aa4f324.json.bz2
diff --git a/.github/test-data/085e81c0-7a95-ef02-16ef-aa1b4344deed.json.bz2 b/.github/test-data/synthea/085e81c0-7a95-ef02-16ef-aa1b4344deed.json.bz2
similarity index 100%
rename from .github/test-data/085e81c0-7a95-ef02-16ef-aa1b4344deed.json.bz2
rename to .github/test-data/synthea/085e81c0-7a95-ef02-16ef-aa1b4344deed.json.bz2
diff --git a/.github/test-data/098fc002-b87e-49dc-4b8e-8900a1bc8661.json.bz2 b/.github/test-data/synthea/098fc002-b87e-49dc-4b8e-8900a1bc8661.json.bz2
similarity index 100%
rename from .github/test-data/098fc002-b87e-49dc-4b8e-8900a1bc8661.json.bz2
rename to .github/test-data/synthea/098fc002-b87e-49dc-4b8e-8900a1bc8661.json.bz2
diff --git a/.github/test-data/0ef7a3b5-53ee-e765-10e2-c63a904ad0fd.json.bz2 b/.github/test-data/synthea/0ef7a3b5-53ee-e765-10e2-c63a904ad0fd.json.bz2
similarity index 100%
rename from .github/test-data/0ef7a3b5-53ee-e765-10e2-c63a904ad0fd.json.bz2
rename to .github/test-data/synthea/0ef7a3b5-53ee-e765-10e2-c63a904ad0fd.json.bz2
diff --git a/.github/test-data/0f2074a0-4173-1a32-988f-5316d7f1cbbe.json.bz2 b/.github/test-data/synthea/0f2074a0-4173-1a32-988f-5316d7f1cbbe.json.bz2
similarity index 100%
rename from .github/test-data/0f2074a0-4173-1a32-988f-5316d7f1cbbe.json.bz2
rename to .github/test-data/synthea/0f2074a0-4173-1a32-988f-5316d7f1cbbe.json.bz2
diff --git a/.github/test-data/1363ed76-25b9-dc4f-6de7-6ee133d82db3.json.bz2 b/.github/test-data/synthea/1363ed76-25b9-dc4f-6de7-6ee133d82db3.json.bz2
similarity index 100%
rename from .github/test-data/1363ed76-25b9-dc4f-6de7-6ee133d82db3.json.bz2
rename to .github/test-data/synthea/1363ed76-25b9-dc4f-6de7-6ee133d82db3.json.bz2
diff --git a/.github/test-data/13956cdf-f7cc-1cd7-9c99-eb796db62ec7.json.bz2 b/.github/test-data/synthea/13956cdf-f7cc-1cd7-9c99-eb796db62ec7.json.bz2
similarity index 100%
rename from .github/test-data/13956cdf-f7cc-1cd7-9c99-eb796db62ec7.json.bz2
rename to .github/test-data/synthea/13956cdf-f7cc-1cd7-9c99-eb796db62ec7.json.bz2
diff --git a/.github/test-data/18be282b-67b9-d958-226a-c5510e5ef0c2.json.bz2 b/.github/test-data/synthea/18be282b-67b9-d958-226a-c5510e5ef0c2.json.bz2
similarity index 100%
rename from .github/test-data/18be282b-67b9-d958-226a-c5510e5ef0c2.json.bz2
rename to .github/test-data/synthea/18be282b-67b9-d958-226a-c5510e5ef0c2.json.bz2
diff --git a/.github/test-data/19625ee6-1a94-1a6a-ca95-40c4efbbdfc7.json.bz2 b/.github/test-data/synthea/19625ee6-1a94-1a6a-ca95-40c4efbbdfc7.json.bz2
similarity index 100%
rename from .github/test-data/19625ee6-1a94-1a6a-ca95-40c4efbbdfc7.json.bz2
rename to .github/test-data/synthea/19625ee6-1a94-1a6a-ca95-40c4efbbdfc7.json.bz2
diff --git a/.github/test-data/1ae8d602-4b41-4571-8c49-b460a22892c2.json.bz2 b/.github/test-data/synthea/1ae8d602-4b41-4571-8c49-b460a22892c2.json.bz2
similarity index 100%
rename from .github/test-data/1ae8d602-4b41-4571-8c49-b460a22892c2.json.bz2
rename to .github/test-data/synthea/1ae8d602-4b41-4571-8c49-b460a22892c2.json.bz2
diff --git a/.github/test-data/1c574eeb-0f08-37cd-475e-fa4021b62ad3.json.bz2 b/.github/test-data/synthea/1c574eeb-0f08-37cd-475e-fa4021b62ad3.json.bz2
similarity index 100%
rename from .github/test-data/1c574eeb-0f08-37cd-475e-fa4021b62ad3.json.bz2
rename to .github/test-data/synthea/1c574eeb-0f08-37cd-475e-fa4021b62ad3.json.bz2
diff --git a/.github/test-data/23275f24-df5a-6bcf-17cc-ff6507270b1c.json.bz2 b/.github/test-data/synthea/23275f24-df5a-6bcf-17cc-ff6507270b1c.json.bz2
similarity index 100%
rename from .github/test-data/23275f24-df5a-6bcf-17cc-ff6507270b1c.json.bz2
rename to .github/test-data/synthea/23275f24-df5a-6bcf-17cc-ff6507270b1c.json.bz2
diff --git a/.github/test-data/24d82e9b-4114-f230-4318-60474031ec4d.json.bz2 b/.github/test-data/synthea/24d82e9b-4114-f230-4318-60474031ec4d.json.bz2
similarity index 100%
rename from .github/test-data/24d82e9b-4114-f230-4318-60474031ec4d.json.bz2
rename to .github/test-data/synthea/24d82e9b-4114-f230-4318-60474031ec4d.json.bz2
diff --git a/.github/test-data/252abfcc-dd25-a9ce-f187-873a98cecc53.json.bz2 b/.github/test-data/synthea/252abfcc-dd25-a9ce-f187-873a98cecc53.json.bz2
similarity index 100%
rename from .github/test-data/252abfcc-dd25-a9ce-f187-873a98cecc53.json.bz2
rename to .github/test-data/synthea/252abfcc-dd25-a9ce-f187-873a98cecc53.json.bz2
diff --git a/.github/test-data/2ad91c08-1b48-0562-dbb2-79f23c1b692b.json.bz2 b/.github/test-data/synthea/2ad91c08-1b48-0562-dbb2-79f23c1b692b.json.bz2
similarity index 100%
rename from .github/test-data/2ad91c08-1b48-0562-dbb2-79f23c1b692b.json.bz2
rename to .github/test-data/synthea/2ad91c08-1b48-0562-dbb2-79f23c1b692b.json.bz2
diff --git a/.github/test-data/2b208315-4cc4-3d52-e597-a03509645859.json.bz2 b/.github/test-data/synthea/2b208315-4cc4-3d52-e597-a03509645859.json.bz2
similarity index 100%
rename from .github/test-data/2b208315-4cc4-3d52-e597-a03509645859.json.bz2
rename to .github/test-data/synthea/2b208315-4cc4-3d52-e597-a03509645859.json.bz2
diff --git a/.github/test-data/2fcbe29d-94f0-ec20-dcf3-740c45bc08ba.json.bz2 b/.github/test-data/synthea/2fcbe29d-94f0-ec20-dcf3-740c45bc08ba.json.bz2
similarity index 100%
rename from .github/test-data/2fcbe29d-94f0-ec20-dcf3-740c45bc08ba.json.bz2
rename to .github/test-data/synthea/2fcbe29d-94f0-ec20-dcf3-740c45bc08ba.json.bz2
diff --git a/.github/test-data/36ab6ed1-e43f-2903-2a7e-62df3a06702c.json.bz2 b/.github/test-data/synthea/36ab6ed1-e43f-2903-2a7e-62df3a06702c.json.bz2
similarity index 100%
rename from .github/test-data/36ab6ed1-e43f-2903-2a7e-62df3a06702c.json.bz2
rename to .github/test-data/synthea/36ab6ed1-e43f-2903-2a7e-62df3a06702c.json.bz2
diff --git a/.github/test-data/3edde3b8-c705-5e74-5994-e69463d9fc69.json.bz2 b/.github/test-data/synthea/3edde3b8-c705-5e74-5994-e69463d9fc69.json.bz2
similarity index 100%
rename from .github/test-data/3edde3b8-c705-5e74-5994-e69463d9fc69.json.bz2
rename to .github/test-data/synthea/3edde3b8-c705-5e74-5994-e69463d9fc69.json.bz2
diff --git a/.github/test-data/4004a424-c33b-6ced-23c3-c1318e45c419.json.bz2 b/.github/test-data/synthea/4004a424-c33b-6ced-23c3-c1318e45c419.json.bz2
similarity index 100%
rename from .github/test-data/4004a424-c33b-6ced-23c3-c1318e45c419.json.bz2
rename to .github/test-data/synthea/4004a424-c33b-6ced-23c3-c1318e45c419.json.bz2
diff --git a/.github/test-data/44717d84-17d5-cefa-acf9-fe51fddc5d1c.json.bz2 b/.github/test-data/synthea/44717d84-17d5-cefa-acf9-fe51fddc5d1c.json.bz2
similarity index 100%
rename from .github/test-data/44717d84-17d5-cefa-acf9-fe51fddc5d1c.json.bz2
rename to .github/test-data/synthea/44717d84-17d5-cefa-acf9-fe51fddc5d1c.json.bz2
diff --git a/.github/test-data/451e7c69-78b8-9bc9-b8a7-030c4a968215.json.bz2 b/.github/test-data/synthea/451e7c69-78b8-9bc9-b8a7-030c4a968215.json.bz2
similarity index 100%
rename from .github/test-data/451e7c69-78b8-9bc9-b8a7-030c4a968215.json.bz2
rename to .github/test-data/synthea/451e7c69-78b8-9bc9-b8a7-030c4a968215.json.bz2
diff --git a/.github/test-data/4b86befa-fa7e-9285-615f-e081dab3f93c.json.bz2 b/.github/test-data/synthea/4b86befa-fa7e-9285-615f-e081dab3f93c.json.bz2
similarity index 100%
rename from .github/test-data/4b86befa-fa7e-9285-615f-e081dab3f93c.json.bz2
rename to .github/test-data/synthea/4b86befa-fa7e-9285-615f-e081dab3f93c.json.bz2
diff --git a/.github/test-data/4fa27f17-62da-04b8-fcb6-81ba9f5e15af.json.bz2 b/.github/test-data/synthea/4fa27f17-62da-04b8-fcb6-81ba9f5e15af.json.bz2
similarity index 100%
rename from .github/test-data/4fa27f17-62da-04b8-fcb6-81ba9f5e15af.json.bz2
rename to .github/test-data/synthea/4fa27f17-62da-04b8-fcb6-81ba9f5e15af.json.bz2
diff --git a/.github/test-data/5035bbae-27fc-b927-4a9b-7af7fdd536eb.json.bz2 b/.github/test-data/synthea/5035bbae-27fc-b927-4a9b-7af7fdd536eb.json.bz2
similarity index 100%
rename from .github/test-data/5035bbae-27fc-b927-4a9b-7af7fdd536eb.json.bz2
rename to .github/test-data/synthea/5035bbae-27fc-b927-4a9b-7af7fdd536eb.json.bz2
diff --git a/.github/test-data/52ebdcae-3656-1a42-0bfc-c0a718b5158a.json.bz2 b/.github/test-data/synthea/52ebdcae-3656-1a42-0bfc-c0a718b5158a.json.bz2
similarity index 100%
rename from .github/test-data/52ebdcae-3656-1a42-0bfc-c0a718b5158a.json.bz2
rename to .github/test-data/synthea/52ebdcae-3656-1a42-0bfc-c0a718b5158a.json.bz2
diff --git a/.github/test-data/53eac4c0-8d6b-72da-2768-a6d08e687f48.json.bz2 b/.github/test-data/synthea/53eac4c0-8d6b-72da-2768-a6d08e687f48.json.bz2
similarity index 100%
rename from .github/test-data/53eac4c0-8d6b-72da-2768-a6d08e687f48.json.bz2
rename to .github/test-data/synthea/53eac4c0-8d6b-72da-2768-a6d08e687f48.json.bz2
diff --git a/.github/test-data/5656ee0a-e373-844b-92da-9afb6c321e76.json.bz2 b/.github/test-data/synthea/5656ee0a-e373-844b-92da-9afb6c321e76.json.bz2
similarity index 100%
rename from .github/test-data/5656ee0a-e373-844b-92da-9afb6c321e76.json.bz2
rename to .github/test-data/synthea/5656ee0a-e373-844b-92da-9afb6c321e76.json.bz2
diff --git a/.github/test-data/56fce424-2560-0447-a0b0-4502d5abd975.json.bz2 b/.github/test-data/synthea/56fce424-2560-0447-a0b0-4502d5abd975.json.bz2
similarity index 100%
rename from .github/test-data/56fce424-2560-0447-a0b0-4502d5abd975.json.bz2
rename to .github/test-data/synthea/56fce424-2560-0447-a0b0-4502d5abd975.json.bz2
diff --git a/.github/test-data/5875d3aa-192c-6d05-221a-88a9cee35ff9.json.bz2 b/.github/test-data/synthea/5875d3aa-192c-6d05-221a-88a9cee35ff9.json.bz2
similarity index 100%
rename from .github/test-data/5875d3aa-192c-6d05-221a-88a9cee35ff9.json.bz2
rename to .github/test-data/synthea/5875d3aa-192c-6d05-221a-88a9cee35ff9.json.bz2
diff --git a/.github/test-data/5ad53a48-97ae-ca72-0ed8-0a31497f06cf.json.bz2 b/.github/test-data/synthea/5ad53a48-97ae-ca72-0ed8-0a31497f06cf.json.bz2
similarity index 100%
rename from .github/test-data/5ad53a48-97ae-ca72-0ed8-0a31497f06cf.json.bz2
rename to .github/test-data/synthea/5ad53a48-97ae-ca72-0ed8-0a31497f06cf.json.bz2
diff --git a/.github/test-data/5d2a2d08-cf2e-b7ad-a0db-77551a2777ec.json.bz2 b/.github/test-data/synthea/5d2a2d08-cf2e-b7ad-a0db-77551a2777ec.json.bz2
similarity index 100%
rename from .github/test-data/5d2a2d08-cf2e-b7ad-a0db-77551a2777ec.json.bz2
rename to .github/test-data/synthea/5d2a2d08-cf2e-b7ad-a0db-77551a2777ec.json.bz2
diff --git a/.github/test-data/5f66ecbb-b445-1290-4b55-9fc3ddfd569e.json.bz2 b/.github/test-data/synthea/5f66ecbb-b445-1290-4b55-9fc3ddfd569e.json.bz2
similarity index 100%
rename from .github/test-data/5f66ecbb-b445-1290-4b55-9fc3ddfd569e.json.bz2
rename to .github/test-data/synthea/5f66ecbb-b445-1290-4b55-9fc3ddfd569e.json.bz2
diff --git a/.github/test-data/6a63e007-a6e5-9252-0155-79221cb61b60.json.bz2 b/.github/test-data/synthea/6a63e007-a6e5-9252-0155-79221cb61b60.json.bz2
similarity index 100%
rename from .github/test-data/6a63e007-a6e5-9252-0155-79221cb61b60.json.bz2
rename to .github/test-data/synthea/6a63e007-a6e5-9252-0155-79221cb61b60.json.bz2
diff --git a/.github/test-data/6c8f3e83-c351-ed33-c38d-6be101c275d2.json.bz2 b/.github/test-data/synthea/6c8f3e83-c351-ed33-c38d-6be101c275d2.json.bz2
similarity index 100%
rename from .github/test-data/6c8f3e83-c351-ed33-c38d-6be101c275d2.json.bz2
rename to .github/test-data/synthea/6c8f3e83-c351-ed33-c38d-6be101c275d2.json.bz2
diff --git a/.github/test-data/6db9aea3-4f89-5e2a-82d4-b2cd90268bc7.json.bz2 b/.github/test-data/synthea/6db9aea3-4f89-5e2a-82d4-b2cd90268bc7.json.bz2
similarity index 100%
rename from .github/test-data/6db9aea3-4f89-5e2a-82d4-b2cd90268bc7.json.bz2
rename to .github/test-data/synthea/6db9aea3-4f89-5e2a-82d4-b2cd90268bc7.json.bz2
diff --git a/.github/test-data/718007d0-218e-d904-c3ec-0f23d4d2cd8b.json.bz2 b/.github/test-data/synthea/718007d0-218e-d904-c3ec-0f23d4d2cd8b.json.bz2
similarity index 100%
rename from .github/test-data/718007d0-218e-d904-c3ec-0f23d4d2cd8b.json.bz2
rename to .github/test-data/synthea/718007d0-218e-d904-c3ec-0f23d4d2cd8b.json.bz2
diff --git a/.github/test-data/72376f6f-a404-ee42-7c9a-45a6b0bdc9f2.json.bz2 b/.github/test-data/synthea/72376f6f-a404-ee42-7c9a-45a6b0bdc9f2.json.bz2
similarity index 100%
rename from .github/test-data/72376f6f-a404-ee42-7c9a-45a6b0bdc9f2.json.bz2
rename to .github/test-data/synthea/72376f6f-a404-ee42-7c9a-45a6b0bdc9f2.json.bz2
diff --git a/.github/test-data/7277a553-d195-6596-0124-b482d859691e.json.bz2 b/.github/test-data/synthea/7277a553-d195-6596-0124-b482d859691e.json.bz2
similarity index 100%
rename from .github/test-data/7277a553-d195-6596-0124-b482d859691e.json.bz2
rename to .github/test-data/synthea/7277a553-d195-6596-0124-b482d859691e.json.bz2
diff --git a/.github/test-data/7278ffc8-5b59-8cb5-8419-294639a9908f.json.bz2 b/.github/test-data/synthea/7278ffc8-5b59-8cb5-8419-294639a9908f.json.bz2
similarity index 100%
rename from .github/test-data/7278ffc8-5b59-8cb5-8419-294639a9908f.json.bz2
rename to .github/test-data/synthea/7278ffc8-5b59-8cb5-8419-294639a9908f.json.bz2
diff --git a/.github/test-data/728248bf-a984-5d08-efff-c44f98f56435.json.bz2 b/.github/test-data/synthea/728248bf-a984-5d08-efff-c44f98f56435.json.bz2
similarity index 100%
rename from .github/test-data/728248bf-a984-5d08-efff-c44f98f56435.json.bz2
rename to .github/test-data/synthea/728248bf-a984-5d08-efff-c44f98f56435.json.bz2
diff --git a/.github/test-data/72b9ff2f-b285-2dd1-b020-eb672210c016.json.bz2 b/.github/test-data/synthea/72b9ff2f-b285-2dd1-b020-eb672210c016.json.bz2
similarity index 100%
rename from .github/test-data/72b9ff2f-b285-2dd1-b020-eb672210c016.json.bz2
rename to .github/test-data/synthea/72b9ff2f-b285-2dd1-b020-eb672210c016.json.bz2
diff --git a/.github/test-data/738c6a70-cd4d-1ec9-077e-1828484674b4.json.bz2 b/.github/test-data/synthea/738c6a70-cd4d-1ec9-077e-1828484674b4.json.bz2
similarity index 100%
rename from .github/test-data/738c6a70-cd4d-1ec9-077e-1828484674b4.json.bz2
rename to .github/test-data/synthea/738c6a70-cd4d-1ec9-077e-1828484674b4.json.bz2
diff --git a/.github/test-data/76f217df-3176-7627-8fef-e60a9b3574c2.json.bz2 b/.github/test-data/synthea/76f217df-3176-7627-8fef-e60a9b3574c2.json.bz2
similarity index 100%
rename from .github/test-data/76f217df-3176-7627-8fef-e60a9b3574c2.json.bz2
rename to .github/test-data/synthea/76f217df-3176-7627-8fef-e60a9b3574c2.json.bz2
diff --git a/.github/test-data/771500c7-1f71-f706-1c07-155670e2db3a.json.bz2 b/.github/test-data/synthea/771500c7-1f71-f706-1c07-155670e2db3a.json.bz2
similarity index 100%
rename from .github/test-data/771500c7-1f71-f706-1c07-155670e2db3a.json.bz2
rename to .github/test-data/synthea/771500c7-1f71-f706-1c07-155670e2db3a.json.bz2
diff --git a/.github/test-data/7a8faea5-1769-a9d8-fa58-a6240f7c252d.json.bz2 b/.github/test-data/synthea/7a8faea5-1769-a9d8-fa58-a6240f7c252d.json.bz2
similarity index 100%
rename from .github/test-data/7a8faea5-1769-a9d8-fa58-a6240f7c252d.json.bz2
rename to .github/test-data/synthea/7a8faea5-1769-a9d8-fa58-a6240f7c252d.json.bz2
diff --git a/.github/test-data/7d8cb13b-3ec2-91af-cfdd-3bb3a0d07039.json.bz2 b/.github/test-data/synthea/7d8cb13b-3ec2-91af-cfdd-3bb3a0d07039.json.bz2
similarity index 100%
rename from .github/test-data/7d8cb13b-3ec2-91af-cfdd-3bb3a0d07039.json.bz2
rename to .github/test-data/synthea/7d8cb13b-3ec2-91af-cfdd-3bb3a0d07039.json.bz2
diff --git a/.github/test-data/83c9c542-0421-9ccb-34f6-8c6876fe04e5.json.bz2 b/.github/test-data/synthea/83c9c542-0421-9ccb-34f6-8c6876fe04e5.json.bz2
similarity index 100%
rename from .github/test-data/83c9c542-0421-9ccb-34f6-8c6876fe04e5.json.bz2
rename to .github/test-data/synthea/83c9c542-0421-9ccb-34f6-8c6876fe04e5.json.bz2
diff --git a/.github/test-data/8682665a-3515-ffeb-39d5-3802f6f36932.json.bz2 b/.github/test-data/synthea/8682665a-3515-ffeb-39d5-3802f6f36932.json.bz2
similarity index 100%
rename from .github/test-data/8682665a-3515-ffeb-39d5-3802f6f36932.json.bz2
rename to .github/test-data/synthea/8682665a-3515-ffeb-39d5-3802f6f36932.json.bz2
diff --git a/.github/test-data/8708d3e1-f718-96bb-03f0-f2a6564ae1cd.json.bz2 b/.github/test-data/synthea/8708d3e1-f718-96bb-03f0-f2a6564ae1cd.json.bz2
similarity index 100%
rename from .github/test-data/8708d3e1-f718-96bb-03f0-f2a6564ae1cd.json.bz2
rename to .github/test-data/synthea/8708d3e1-f718-96bb-03f0-f2a6564ae1cd.json.bz2
diff --git a/.github/test-data/88e4bac8-2609-3c28-a354-ab29f69153f4.json.bz2 b/.github/test-data/synthea/88e4bac8-2609-3c28-a354-ab29f69153f4.json.bz2
similarity index 100%
rename from .github/test-data/88e4bac8-2609-3c28-a354-ab29f69153f4.json.bz2
rename to .github/test-data/synthea/88e4bac8-2609-3c28-a354-ab29f69153f4.json.bz2
diff --git a/.github/test-data/897a61e0-353b-25d1-7806-2a21710cb764.json.bz2 b/.github/test-data/synthea/897a61e0-353b-25d1-7806-2a21710cb764.json.bz2
similarity index 100%
rename from .github/test-data/897a61e0-353b-25d1-7806-2a21710cb764.json.bz2
rename to .github/test-data/synthea/897a61e0-353b-25d1-7806-2a21710cb764.json.bz2
diff --git a/.github/test-data/897eba7c-8b8c-7022-634f-8c69f0702b30.json.bz2 b/.github/test-data/synthea/897eba7c-8b8c-7022-634f-8c69f0702b30.json.bz2
similarity index 100%
rename from .github/test-data/897eba7c-8b8c-7022-634f-8c69f0702b30.json.bz2
rename to .github/test-data/synthea/897eba7c-8b8c-7022-634f-8c69f0702b30.json.bz2
diff --git a/.github/test-data/8a4c9c04-1524-9f1c-d65b-9b17e4520fef.json.bz2 b/.github/test-data/synthea/8a4c9c04-1524-9f1c-d65b-9b17e4520fef.json.bz2
similarity index 100%
rename from .github/test-data/8a4c9c04-1524-9f1c-d65b-9b17e4520fef.json.bz2
rename to .github/test-data/synthea/8a4c9c04-1524-9f1c-d65b-9b17e4520fef.json.bz2
diff --git a/.github/test-data/8dd4ed1f-108e-64ad-ce09-926c83ce7f76.json.bz2 b/.github/test-data/synthea/8dd4ed1f-108e-64ad-ce09-926c83ce7f76.json.bz2
similarity index 100%
rename from .github/test-data/8dd4ed1f-108e-64ad-ce09-926c83ce7f76.json.bz2
rename to .github/test-data/synthea/8dd4ed1f-108e-64ad-ce09-926c83ce7f76.json.bz2
diff --git a/.github/test-data/9478e08e-4573-88e1-7ea2-1b757771da8b.json.bz2 b/.github/test-data/synthea/9478e08e-4573-88e1-7ea2-1b757771da8b.json.bz2
similarity index 100%
rename from .github/test-data/9478e08e-4573-88e1-7ea2-1b757771da8b.json.bz2
rename to .github/test-data/synthea/9478e08e-4573-88e1-7ea2-1b757771da8b.json.bz2
diff --git a/.github/test-data/98f6377c-4f40-745a-04aa-fcb2ce32d9bd.json.bz2 b/.github/test-data/synthea/98f6377c-4f40-745a-04aa-fcb2ce32d9bd.json.bz2
similarity index 100%
rename from .github/test-data/98f6377c-4f40-745a-04aa-fcb2ce32d9bd.json.bz2
rename to .github/test-data/synthea/98f6377c-4f40-745a-04aa-fcb2ce32d9bd.json.bz2
diff --git a/.github/test-data/99e6bacf-7def-f6b6-5f1b-888241c8729a.json.bz2 b/.github/test-data/synthea/99e6bacf-7def-f6b6-5f1b-888241c8729a.json.bz2
similarity index 100%
rename from .github/test-data/99e6bacf-7def-f6b6-5f1b-888241c8729a.json.bz2
rename to .github/test-data/synthea/99e6bacf-7def-f6b6-5f1b-888241c8729a.json.bz2
diff --git a/.github/test-data/9a174f9e-ed67-6617-0106-745fb1f9a344.json.bz2 b/.github/test-data/synthea/9a174f9e-ed67-6617-0106-745fb1f9a344.json.bz2
similarity index 100%
rename from .github/test-data/9a174f9e-ed67-6617-0106-745fb1f9a344.json.bz2
rename to .github/test-data/synthea/9a174f9e-ed67-6617-0106-745fb1f9a344.json.bz2
diff --git a/.github/test-data/9b6fa8e6-e618-17c5-28a8-1095559fd19b.json.bz2 b/.github/test-data/synthea/9b6fa8e6-e618-17c5-28a8-1095559fd19b.json.bz2
similarity index 100%
rename from .github/test-data/9b6fa8e6-e618-17c5-28a8-1095559fd19b.json.bz2
rename to .github/test-data/synthea/9b6fa8e6-e618-17c5-28a8-1095559fd19b.json.bz2
diff --git a/.github/test-data/9d3e5754-acb3-5573-ef17-fe95d83dc941.json.bz2 b/.github/test-data/synthea/9d3e5754-acb3-5573-ef17-fe95d83dc941.json.bz2
similarity index 100%
rename from .github/test-data/9d3e5754-acb3-5573-ef17-fe95d83dc941.json.bz2
rename to .github/test-data/synthea/9d3e5754-acb3-5573-ef17-fe95d83dc941.json.bz2
diff --git a/.github/test-data/9fa1e332-a3eb-52e2-d79a-62042a485967.json.bz2 b/.github/test-data/synthea/9fa1e332-a3eb-52e2-d79a-62042a485967.json.bz2
similarity index 100%
rename from .github/test-data/9fa1e332-a3eb-52e2-d79a-62042a485967.json.bz2
rename to .github/test-data/synthea/9fa1e332-a3eb-52e2-d79a-62042a485967.json.bz2
diff --git a/.github/test-data/9fe7994a-5fec-874c-8452-e45786bcfb0a.json.bz2 b/.github/test-data/synthea/9fe7994a-5fec-874c-8452-e45786bcfb0a.json.bz2
similarity index 100%
rename from .github/test-data/9fe7994a-5fec-874c-8452-e45786bcfb0a.json.bz2
rename to .github/test-data/synthea/9fe7994a-5fec-874c-8452-e45786bcfb0a.json.bz2
diff --git a/.github/test-data/README.md b/.github/test-data/synthea/README.md
similarity index 99%
rename from .github/test-data/README.md
rename to .github/test-data/synthea/README.md
index fcb53ae23..0b69e811e 100644
--- a/.github/test-data/README.md
+++ b/.github/test-data/synthea/README.md
@@ -1,4 +1,4 @@
-# FHIR Test Data
+# FHIR Synthea Test Data
Generates with Synthea v2.7.0 using openjdk 11.
@@ -269,4 +269,4 @@ Max Age: 140
98 -- Billy698 Homenick806 (78 y/o M) Newton, Massachusetts
93 -- Karine844 Blanda868 (58 y/o F) Worcester, Massachusetts
Records: total=120, alive=100, dead=20
-```
\ No newline at end of file
+```
diff --git a/.github/test-data/a1935ff2-8d78-6259-e537-1036c451d997.json.bz2 b/.github/test-data/synthea/a1935ff2-8d78-6259-e537-1036c451d997.json.bz2
similarity index 100%
rename from .github/test-data/a1935ff2-8d78-6259-e537-1036c451d997.json.bz2
rename to .github/test-data/synthea/a1935ff2-8d78-6259-e537-1036c451d997.json.bz2
diff --git a/.github/test-data/a47131c6-a60c-4a8e-f099-0ae21c7969ff.json.bz2 b/.github/test-data/synthea/a47131c6-a60c-4a8e-f099-0ae21c7969ff.json.bz2
similarity index 100%
rename from .github/test-data/a47131c6-a60c-4a8e-f099-0ae21c7969ff.json.bz2
rename to .github/test-data/synthea/a47131c6-a60c-4a8e-f099-0ae21c7969ff.json.bz2
diff --git a/.github/test-data/a8327210-6158-2be1-fb72-553a78a0ff37.json.bz2 b/.github/test-data/synthea/a8327210-6158-2be1-fb72-553a78a0ff37.json.bz2
similarity index 100%
rename from .github/test-data/a8327210-6158-2be1-fb72-553a78a0ff37.json.bz2
rename to .github/test-data/synthea/a8327210-6158-2be1-fb72-553a78a0ff37.json.bz2
diff --git a/.github/test-data/a8376487-72d8-ac29-a654-91f3622cc7a4.json.bz2 b/.github/test-data/synthea/a8376487-72d8-ac29-a654-91f3622cc7a4.json.bz2
similarity index 100%
rename from .github/test-data/a8376487-72d8-ac29-a654-91f3622cc7a4.json.bz2
rename to .github/test-data/synthea/a8376487-72d8-ac29-a654-91f3622cc7a4.json.bz2
diff --git a/.github/test-data/a97a7383-b712-e276-4cc1-51e4b4e84c13.json.bz2 b/.github/test-data/synthea/a97a7383-b712-e276-4cc1-51e4b4e84c13.json.bz2
similarity index 100%
rename from .github/test-data/a97a7383-b712-e276-4cc1-51e4b4e84c13.json.bz2
rename to .github/test-data/synthea/a97a7383-b712-e276-4cc1-51e4b4e84c13.json.bz2
diff --git a/.github/test-data/aaac7c75-2413-47f0-6696-19d645ae5eda.json.bz2 b/.github/test-data/synthea/aaac7c75-2413-47f0-6696-19d645ae5eda.json.bz2
similarity index 100%
rename from .github/test-data/aaac7c75-2413-47f0-6696-19d645ae5eda.json.bz2
rename to .github/test-data/synthea/aaac7c75-2413-47f0-6696-19d645ae5eda.json.bz2
diff --git a/.github/test-data/ab5537a3-8608-5f56-53f5-d10b00eb4680.json.bz2 b/.github/test-data/synthea/ab5537a3-8608-5f56-53f5-d10b00eb4680.json.bz2
similarity index 100%
rename from .github/test-data/ab5537a3-8608-5f56-53f5-d10b00eb4680.json.bz2
rename to .github/test-data/synthea/ab5537a3-8608-5f56-53f5-d10b00eb4680.json.bz2
diff --git a/.github/test-data/ac22410a-b0e0-31eb-5ff2-2a3a47f1cff0.json.bz2 b/.github/test-data/synthea/ac22410a-b0e0-31eb-5ff2-2a3a47f1cff0.json.bz2
similarity index 100%
rename from .github/test-data/ac22410a-b0e0-31eb-5ff2-2a3a47f1cff0.json.bz2
rename to .github/test-data/synthea/ac22410a-b0e0-31eb-5ff2-2a3a47f1cff0.json.bz2
diff --git a/.github/test-data/acd56837-aaab-5825-8f24-784319fc02df.json.bz2 b/.github/test-data/synthea/acd56837-aaab-5825-8f24-784319fc02df.json.bz2
similarity index 100%
rename from .github/test-data/acd56837-aaab-5825-8f24-784319fc02df.json.bz2
rename to .github/test-data/synthea/acd56837-aaab-5825-8f24-784319fc02df.json.bz2
diff --git a/.github/test-data/ad0b4b7a-2285-7a3c-5fd2-edbe4d67b7e7.json.bz2 b/.github/test-data/synthea/ad0b4b7a-2285-7a3c-5fd2-edbe4d67b7e7.json.bz2
similarity index 100%
rename from .github/test-data/ad0b4b7a-2285-7a3c-5fd2-edbe4d67b7e7.json.bz2
rename to .github/test-data/synthea/ad0b4b7a-2285-7a3c-5fd2-edbe4d67b7e7.json.bz2
diff --git a/.github/test-data/b08d10a2-5031-379f-0157-ddceb2196440.json.bz2 b/.github/test-data/synthea/b08d10a2-5031-379f-0157-ddceb2196440.json.bz2
similarity index 100%
rename from .github/test-data/b08d10a2-5031-379f-0157-ddceb2196440.json.bz2
rename to .github/test-data/synthea/b08d10a2-5031-379f-0157-ddceb2196440.json.bz2
diff --git a/.github/test-data/b3664f86-0ce9-4a2c-ae85-4d390d438512.json.bz2 b/.github/test-data/synthea/b3664f86-0ce9-4a2c-ae85-4d390d438512.json.bz2
similarity index 100%
rename from .github/test-data/b3664f86-0ce9-4a2c-ae85-4d390d438512.json.bz2
rename to .github/test-data/synthea/b3664f86-0ce9-4a2c-ae85-4d390d438512.json.bz2
diff --git a/.github/test-data/b62462f8-e515-7cdd-449d-e03b38e976e1.json.bz2 b/.github/test-data/synthea/b62462f8-e515-7cdd-449d-e03b38e976e1.json.bz2
similarity index 100%
rename from .github/test-data/b62462f8-e515-7cdd-449d-e03b38e976e1.json.bz2
rename to .github/test-data/synthea/b62462f8-e515-7cdd-449d-e03b38e976e1.json.bz2
diff --git a/.github/test-data/b6f92fa3-b989-fa1b-aad8-aafb1020a5e9.json.bz2 b/.github/test-data/synthea/b6f92fa3-b989-fa1b-aad8-aafb1020a5e9.json.bz2
similarity index 100%
rename from .github/test-data/b6f92fa3-b989-fa1b-aad8-aafb1020a5e9.json.bz2
rename to .github/test-data/synthea/b6f92fa3-b989-fa1b-aad8-aafb1020a5e9.json.bz2
diff --git a/.github/test-data/b7dbbc09-0370-0e9f-dc4b-46f41e48b82d.json.bz2 b/.github/test-data/synthea/b7dbbc09-0370-0e9f-dc4b-46f41e48b82d.json.bz2
similarity index 100%
rename from .github/test-data/b7dbbc09-0370-0e9f-dc4b-46f41e48b82d.json.bz2
rename to .github/test-data/synthea/b7dbbc09-0370-0e9f-dc4b-46f41e48b82d.json.bz2
diff --git a/.github/test-data/b9590b16-804d-3d9f-0de0-b80b794f1017.json.bz2 b/.github/test-data/synthea/b9590b16-804d-3d9f-0de0-b80b794f1017.json.bz2
similarity index 100%
rename from .github/test-data/b9590b16-804d-3d9f-0de0-b80b794f1017.json.bz2
rename to .github/test-data/synthea/b9590b16-804d-3d9f-0de0-b80b794f1017.json.bz2
diff --git a/.github/test-data/bba190d1-1356-0588-7a1b-7e1325835baa.json.bz2 b/.github/test-data/synthea/bba190d1-1356-0588-7a1b-7e1325835baa.json.bz2
similarity index 100%
rename from .github/test-data/bba190d1-1356-0588-7a1b-7e1325835baa.json.bz2
rename to .github/test-data/synthea/bba190d1-1356-0588-7a1b-7e1325835baa.json.bz2
diff --git a/.github/test-data/be9d18f7-f230-dadc-049e-c13d3a4ac079.json.bz2 b/.github/test-data/synthea/be9d18f7-f230-dadc-049e-c13d3a4ac079.json.bz2
similarity index 100%
rename from .github/test-data/be9d18f7-f230-dadc-049e-c13d3a4ac079.json.bz2
rename to .github/test-data/synthea/be9d18f7-f230-dadc-049e-c13d3a4ac079.json.bz2
diff --git a/.github/test-data/beb53716-4df8-a51c-c58e-a8b814b8ac88.json.bz2 b/.github/test-data/synthea/beb53716-4df8-a51c-c58e-a8b814b8ac88.json.bz2
similarity index 100%
rename from .github/test-data/beb53716-4df8-a51c-c58e-a8b814b8ac88.json.bz2
rename to .github/test-data/synthea/beb53716-4df8-a51c-c58e-a8b814b8ac88.json.bz2
diff --git a/.github/test-data/c0697745-be05-4abc-07e0-f78ca6cb7230.json.bz2 b/.github/test-data/synthea/c0697745-be05-4abc-07e0-f78ca6cb7230.json.bz2
similarity index 100%
rename from .github/test-data/c0697745-be05-4abc-07e0-f78ca6cb7230.json.bz2
rename to .github/test-data/synthea/c0697745-be05-4abc-07e0-f78ca6cb7230.json.bz2
diff --git a/.github/test-data/c1933e20-95c2-61c5-684b-7554a943648b.json.bz2 b/.github/test-data/synthea/c1933e20-95c2-61c5-684b-7554a943648b.json.bz2
similarity index 100%
rename from .github/test-data/c1933e20-95c2-61c5-684b-7554a943648b.json.bz2
rename to .github/test-data/synthea/c1933e20-95c2-61c5-684b-7554a943648b.json.bz2
diff --git a/.github/test-data/c4bf405e-26ad-4bb9-e17c-9ee3a40f86c6.json.bz2 b/.github/test-data/synthea/c4bf405e-26ad-4bb9-e17c-9ee3a40f86c6.json.bz2
similarity index 100%
rename from .github/test-data/c4bf405e-26ad-4bb9-e17c-9ee3a40f86c6.json.bz2
rename to .github/test-data/synthea/c4bf405e-26ad-4bb9-e17c-9ee3a40f86c6.json.bz2
diff --git a/.github/test-data/c535373c-cbac-c4cd-3281-8eaa9dcc116d.json.bz2 b/.github/test-data/synthea/c535373c-cbac-c4cd-3281-8eaa9dcc116d.json.bz2
similarity index 100%
rename from .github/test-data/c535373c-cbac-c4cd-3281-8eaa9dcc116d.json.bz2
rename to .github/test-data/synthea/c535373c-cbac-c4cd-3281-8eaa9dcc116d.json.bz2
diff --git a/.github/test-data/c5c9dbe6-4370-55b5-f14f-3374b173753e.json.bz2 b/.github/test-data/synthea/c5c9dbe6-4370-55b5-f14f-3374b173753e.json.bz2
similarity index 100%
rename from .github/test-data/c5c9dbe6-4370-55b5-f14f-3374b173753e.json.bz2
rename to .github/test-data/synthea/c5c9dbe6-4370-55b5-f14f-3374b173753e.json.bz2
diff --git a/.github/test-data/c94995d9-8ee6-7c32-2b54-acb14e716901.json.bz2 b/.github/test-data/synthea/c94995d9-8ee6-7c32-2b54-acb14e716901.json.bz2
similarity index 100%
rename from .github/test-data/c94995d9-8ee6-7c32-2b54-acb14e716901.json.bz2
rename to .github/test-data/synthea/c94995d9-8ee6-7c32-2b54-acb14e716901.json.bz2
diff --git a/.github/test-data/cd185ab5-8efb-c68a-4779-d49dd4ba8f28.json.bz2 b/.github/test-data/synthea/cd185ab5-8efb-c68a-4779-d49dd4ba8f28.json.bz2
similarity index 100%
rename from .github/test-data/cd185ab5-8efb-c68a-4779-d49dd4ba8f28.json.bz2
rename to .github/test-data/synthea/cd185ab5-8efb-c68a-4779-d49dd4ba8f28.json.bz2
diff --git a/.github/test-data/cdb9464f-4968-0f08-c49d-b0b85254620f.json.bz2 b/.github/test-data/synthea/cdb9464f-4968-0f08-c49d-b0b85254620f.json.bz2
similarity index 100%
rename from .github/test-data/cdb9464f-4968-0f08-c49d-b0b85254620f.json.bz2
rename to .github/test-data/synthea/cdb9464f-4968-0f08-c49d-b0b85254620f.json.bz2
diff --git a/.github/test-data/cee84886-eadf-fbeb-d9b9-91321b5d213f.json.bz2 b/.github/test-data/synthea/cee84886-eadf-fbeb-d9b9-91321b5d213f.json.bz2
similarity index 100%
rename from .github/test-data/cee84886-eadf-fbeb-d9b9-91321b5d213f.json.bz2
rename to .github/test-data/synthea/cee84886-eadf-fbeb-d9b9-91321b5d213f.json.bz2
diff --git a/.github/test-data/d1193889-ebd9-4e35-bf1b-8a73ecbfc00b.json.bz2 b/.github/test-data/synthea/d1193889-ebd9-4e35-bf1b-8a73ecbfc00b.json.bz2
similarity index 100%
rename from .github/test-data/d1193889-ebd9-4e35-bf1b-8a73ecbfc00b.json.bz2
rename to .github/test-data/synthea/d1193889-ebd9-4e35-bf1b-8a73ecbfc00b.json.bz2
diff --git a/.github/test-data/d6149fdd-6607-bbc6-731a-519f920e7c88.json.bz2 b/.github/test-data/synthea/d6149fdd-6607-bbc6-731a-519f920e7c88.json.bz2
similarity index 100%
rename from .github/test-data/d6149fdd-6607-bbc6-731a-519f920e7c88.json.bz2
rename to .github/test-data/synthea/d6149fdd-6607-bbc6-731a-519f920e7c88.json.bz2
diff --git a/.github/test-data/d614dcb6-435f-be94-5344-00143898b1c3.json.bz2 b/.github/test-data/synthea/d614dcb6-435f-be94-5344-00143898b1c3.json.bz2
similarity index 100%
rename from .github/test-data/d614dcb6-435f-be94-5344-00143898b1c3.json.bz2
rename to .github/test-data/synthea/d614dcb6-435f-be94-5344-00143898b1c3.json.bz2
diff --git a/.github/test-data/da203ade-58db-ae38-3608-f20843a86759.json.bz2 b/.github/test-data/synthea/da203ade-58db-ae38-3608-f20843a86759.json.bz2
similarity index 100%
rename from .github/test-data/da203ade-58db-ae38-3608-f20843a86759.json.bz2
rename to .github/test-data/synthea/da203ade-58db-ae38-3608-f20843a86759.json.bz2
diff --git a/.github/test-data/dd4d5564-3cdd-19ce-8efc-f30e5395f5c6.json.bz2 b/.github/test-data/synthea/dd4d5564-3cdd-19ce-8efc-f30e5395f5c6.json.bz2
similarity index 100%
rename from .github/test-data/dd4d5564-3cdd-19ce-8efc-f30e5395f5c6.json.bz2
rename to .github/test-data/synthea/dd4d5564-3cdd-19ce-8efc-f30e5395f5c6.json.bz2
diff --git a/.github/test-data/dd92a3e7-d1db-c15a-f8fe-e3847b7f07b1.json.bz2 b/.github/test-data/synthea/dd92a3e7-d1db-c15a-f8fe-e3847b7f07b1.json.bz2
similarity index 100%
rename from .github/test-data/dd92a3e7-d1db-c15a-f8fe-e3847b7f07b1.json.bz2
rename to .github/test-data/synthea/dd92a3e7-d1db-c15a-f8fe-e3847b7f07b1.json.bz2
diff --git a/.github/test-data/e0d320aa-cba1-6d50-ef4a-56191eb00c41.json.bz2 b/.github/test-data/synthea/e0d320aa-cba1-6d50-ef4a-56191eb00c41.json.bz2
similarity index 100%
rename from .github/test-data/e0d320aa-cba1-6d50-ef4a-56191eb00c41.json.bz2
rename to .github/test-data/synthea/e0d320aa-cba1-6d50-ef4a-56191eb00c41.json.bz2
diff --git a/.github/test-data/e1404dc3-4e21-84ae-cdcf-89d04084020c.json.bz2 b/.github/test-data/synthea/e1404dc3-4e21-84ae-cdcf-89d04084020c.json.bz2
similarity index 100%
rename from .github/test-data/e1404dc3-4e21-84ae-cdcf-89d04084020c.json.bz2
rename to .github/test-data/synthea/e1404dc3-4e21-84ae-cdcf-89d04084020c.json.bz2
diff --git a/.github/test-data/e1dbcb04-9c64-e94c-2bd0-d7b199d369e5.json.bz2 b/.github/test-data/synthea/e1dbcb04-9c64-e94c-2bd0-d7b199d369e5.json.bz2
similarity index 100%
rename from .github/test-data/e1dbcb04-9c64-e94c-2bd0-d7b199d369e5.json.bz2
rename to .github/test-data/synthea/e1dbcb04-9c64-e94c-2bd0-d7b199d369e5.json.bz2
diff --git a/.github/test-data/e2053282-a9da-7d0c-8683-481ae0b8c75c.json.bz2 b/.github/test-data/synthea/e2053282-a9da-7d0c-8683-481ae0b8c75c.json.bz2
similarity index 100%
rename from .github/test-data/e2053282-a9da-7d0c-8683-481ae0b8c75c.json.bz2
rename to .github/test-data/synthea/e2053282-a9da-7d0c-8683-481ae0b8c75c.json.bz2
diff --git a/.github/test-data/e2d6fb82-fce6-063b-a9b1-554d585bb268.json.bz2 b/.github/test-data/synthea/e2d6fb82-fce6-063b-a9b1-554d585bb268.json.bz2
similarity index 100%
rename from .github/test-data/e2d6fb82-fce6-063b-a9b1-554d585bb268.json.bz2
rename to .github/test-data/synthea/e2d6fb82-fce6-063b-a9b1-554d585bb268.json.bz2
diff --git a/.github/test-data/e3ba24ed-aad7-86db-2646-4c510dfd7280.json.bz2 b/.github/test-data/synthea/e3ba24ed-aad7-86db-2646-4c510dfd7280.json.bz2
similarity index 100%
rename from .github/test-data/e3ba24ed-aad7-86db-2646-4c510dfd7280.json.bz2
rename to .github/test-data/synthea/e3ba24ed-aad7-86db-2646-4c510dfd7280.json.bz2
diff --git a/.github/test-data/e5a8d3f4-4484-ebfd-7404-d9f02c9fe6a6.json.bz2 b/.github/test-data/synthea/e5a8d3f4-4484-ebfd-7404-d9f02c9fe6a6.json.bz2
similarity index 100%
rename from .github/test-data/e5a8d3f4-4484-ebfd-7404-d9f02c9fe6a6.json.bz2
rename to .github/test-data/synthea/e5a8d3f4-4484-ebfd-7404-d9f02c9fe6a6.json.bz2
diff --git a/.github/test-data/e660ef94-5bfc-04d6-c321-c5baaf41cfb8.json.bz2 b/.github/test-data/synthea/e660ef94-5bfc-04d6-c321-c5baaf41cfb8.json.bz2
similarity index 100%
rename from .github/test-data/e660ef94-5bfc-04d6-c321-c5baaf41cfb8.json.bz2
rename to .github/test-data/synthea/e660ef94-5bfc-04d6-c321-c5baaf41cfb8.json.bz2
diff --git a/.github/test-data/e78fd9c5-5c89-26ca-d397-e9da30700444.json.bz2 b/.github/test-data/synthea/e78fd9c5-5c89-26ca-d397-e9da30700444.json.bz2
similarity index 100%
rename from .github/test-data/e78fd9c5-5c89-26ca-d397-e9da30700444.json.bz2
rename to .github/test-data/synthea/e78fd9c5-5c89-26ca-d397-e9da30700444.json.bz2
diff --git a/.github/test-data/e8247f30-fc71-a582-66e5-1c2c0c097fc8.json.bz2 b/.github/test-data/synthea/e8247f30-fc71-a582-66e5-1c2c0c097fc8.json.bz2
similarity index 100%
rename from .github/test-data/e8247f30-fc71-a582-66e5-1c2c0c097fc8.json.bz2
rename to .github/test-data/synthea/e8247f30-fc71-a582-66e5-1c2c0c097fc8.json.bz2
diff --git a/.github/test-data/ea84fe02-2e40-bf0f-da50-56d2786b8162.json.bz2 b/.github/test-data/synthea/ea84fe02-2e40-bf0f-da50-56d2786b8162.json.bz2
similarity index 100%
rename from .github/test-data/ea84fe02-2e40-bf0f-da50-56d2786b8162.json.bz2
rename to .github/test-data/synthea/ea84fe02-2e40-bf0f-da50-56d2786b8162.json.bz2
diff --git a/.github/test-data/eff34607-816a-5c0c-0ed5-47587311b1e9.json.bz2 b/.github/test-data/synthea/eff34607-816a-5c0c-0ed5-47587311b1e9.json.bz2
similarity index 100%
rename from .github/test-data/eff34607-816a-5c0c-0ed5-47587311b1e9.json.bz2
rename to .github/test-data/synthea/eff34607-816a-5c0c-0ed5-47587311b1e9.json.bz2
diff --git a/.github/test-data/effb1622-6779-27de-dd68-ba7a53a99eb2.json.bz2 b/.github/test-data/synthea/effb1622-6779-27de-dd68-ba7a53a99eb2.json.bz2
similarity index 100%
rename from .github/test-data/effb1622-6779-27de-dd68-ba7a53a99eb2.json.bz2
rename to .github/test-data/synthea/effb1622-6779-27de-dd68-ba7a53a99eb2.json.bz2
diff --git a/.github/test-data/f0f322e5-2683-5a04-0e17-3b765f92072f.json.bz2 b/.github/test-data/synthea/f0f322e5-2683-5a04-0e17-3b765f92072f.json.bz2
similarity index 100%
rename from .github/test-data/f0f322e5-2683-5a04-0e17-3b765f92072f.json.bz2
rename to .github/test-data/synthea/f0f322e5-2683-5a04-0e17-3b765f92072f.json.bz2
diff --git a/.github/test-data/f500d29f-be62-9008-43c5-e2c173dde9bd.json.bz2 b/.github/test-data/synthea/f500d29f-be62-9008-43c5-e2c173dde9bd.json.bz2
similarity index 100%
rename from .github/test-data/f500d29f-be62-9008-43c5-e2c173dde9bd.json.bz2
rename to .github/test-data/synthea/f500d29f-be62-9008-43c5-e2c173dde9bd.json.bz2
diff --git a/.github/test-data/f804dced-f61f-f1a9-00ef-01b81ed2c6f9.json.bz2 b/.github/test-data/synthea/f804dced-f61f-f1a9-00ef-01b81ed2c6f9.json.bz2
similarity index 100%
rename from .github/test-data/f804dced-f61f-f1a9-00ef-01b81ed2c6f9.json.bz2
rename to .github/test-data/synthea/f804dced-f61f-f1a9-00ef-01b81ed2c6f9.json.bz2
diff --git a/.github/test-data/f92fdc8c-3fad-641d-d003-45ed72b50a12.json.bz2 b/.github/test-data/synthea/f92fdc8c-3fad-641d-d003-45ed72b50a12.json.bz2
similarity index 100%
rename from .github/test-data/f92fdc8c-3fad-641d-d003-45ed72b50a12.json.bz2
rename to .github/test-data/synthea/f92fdc8c-3fad-641d-d003-45ed72b50a12.json.bz2
diff --git a/.github/test-data/fa7ff0de-a190-28a1-ccb8-515bc6ee8541.json.bz2 b/.github/test-data/synthea/fa7ff0de-a190-28a1-ccb8-515bc6ee8541.json.bz2
similarity index 100%
rename from .github/test-data/fa7ff0de-a190-28a1-ccb8-515bc6ee8541.json.bz2
rename to .github/test-data/synthea/fa7ff0de-a190-28a1-ccb8-515bc6ee8541.json.bz2
diff --git a/.github/test-data/fb08980f-4a77-f46d-0b2c-dba79a247437.json.bz2 b/.github/test-data/synthea/fb08980f-4a77-f46d-0b2c-dba79a247437.json.bz2
similarity index 100%
rename from .github/test-data/fb08980f-4a77-f46d-0b2c-dba79a247437.json.bz2
rename to .github/test-data/synthea/fb08980f-4a77-f46d-0b2c-dba79a247437.json.bz2
diff --git a/.github/test-data/fbe5ba5b-cb6a-c511-7ada-612173191d63.json.bz2 b/.github/test-data/synthea/fbe5ba5b-cb6a-c511-7ada-612173191d63.json.bz2
similarity index 100%
rename from .github/test-data/fbe5ba5b-cb6a-c511-7ada-612173191d63.json.bz2
rename to .github/test-data/synthea/fbe5ba5b-cb6a-c511-7ada-612173191d63.json.bz2
diff --git a/.github/test-data/fcd31792-91d8-982e-8e28-ef1eb284e260.json.bz2 b/.github/test-data/synthea/fcd31792-91d8-982e-8e28-ef1eb284e260.json.bz2
similarity index 100%
rename from .github/test-data/fcd31792-91d8-982e-8e28-ef1eb284e260.json.bz2
rename to .github/test-data/synthea/fcd31792-91d8-982e-8e28-ef1eb284e260.json.bz2
diff --git a/.github/test-data/fee04478-ddcd-4fe8-02c4-d15fe97bbce3.json.bz2 b/.github/test-data/synthea/fee04478-ddcd-4fe8-02c4-d15fe97bbce3.json.bz2
similarity index 100%
rename from .github/test-data/fee04478-ddcd-4fe8-02c4-d15fe97bbce3.json.bz2
rename to .github/test-data/synthea/fee04478-ddcd-4fe8-02c4-d15fe97bbce3.json.bz2
diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml
index 10c85e5c8..36788b519 100644
--- a/.github/workflows/build.yml
+++ b/.github/workflows/build.yml
@@ -303,17 +303,6 @@ jobs:
- name: Check out Git repository
uses: actions/checkout@v2
- - name: Setup Java
- uses: actions/setup-java@v2
- with:
- distribution: 'temurin'
- java-version: '17'
-
- - name: Setup Clojure
- uses: DeLaGuardo/setup-clojure@master
- with:
- tools-deps: '1.10.3.1029'
-
- name: Install Blazectl
run: .github/scripts/install-blazectl.sh
@@ -339,8 +328,14 @@ jobs:
- name: Check Capability Statement
run: .github/scripts/check-capability-statement.sh
+ - name: Check Referential Integrity Enforced
+ run: .github/scripts/check-referential-integrity-enforced.sh
+
- name: Load Data
- run: blazectl --server http://localhost:8080/fhir upload .github/test-data
+ run: blazectl --server http://localhost:8080/fhir upload .github/test-data/synthea
+
+ - name: Check Total-Number of Resources are 92114
+ run: .github/scripts/check-total-number-of-resources.sh 92114
- name: Count Resources
run: blazectl --server http://localhost:8080/fhir count-resources
@@ -459,6 +454,48 @@ jobs:
- name: Prometheus Metrics
run: curl -f http://localhost:8081/metrics
+ not-enforcing-referential-integrity-test:
+ needs: build
+ runs-on: ubuntu-20.04
+
+ steps:
+ - name: Check out Git repository
+ uses: actions/checkout@v2
+
+ - name: Install Blazectl
+ run: .github/scripts/install-blazectl.sh
+
+ - name: Login to GitHub Container Registry
+ uses: docker/login-action@v1
+ with:
+ registry: ghcr.io
+ username: ${{ github.repository_owner }}
+ password: ${{ secrets.CR_PAT }}
+
+ - name: Pull Docker Image
+ run: docker pull ghcr.io/samply/blaze:sha-${{ github.sha }}
+
+ - name: Run Blaze
+ run: docker run --name blaze -d -e JAVA_TOOL_OPTIONS=-Xmx2g -e ENFORCE_REFERENTIAL_INTEGRITY=false -p 8080:8080 -v blaze-data:/app/data ghcr.io/samply/blaze:sha-${{ github.sha }}
+
+ - name: Sleep 60 Seconds
+ run: sleep 60
+
+ - name: Docker Logs
+ run: docker logs blaze
+
+ - name: Check Capability Statement
+ run: .github/scripts/check-capability-statement.sh
+
+ - name: Check Referential Integrity Not Enforced
+ run: .github/scripts/check-referential-integrity-not-enforced.sh
+
+ - name: Load Data
+ run: blazectl --server http://localhost:8080/fhir upload -c1 .github/test-data/etl
+
+ - name: Check Total-Number of Resources are 5
+ run: .github/scripts/check-total-number-of-resources.sh 5
+
jepsen-test:
needs: build
runs-on: ubuntu-20.04
@@ -556,23 +593,6 @@ jobs:
- name: Check out Git repository
uses: actions/checkout@v2
- - name: Setup Java
- uses: actions/setup-java@v2
- with:
- distribution: 'temurin'
- java-version: '17'
-
- - name: Setup Clojure
- uses: DeLaGuardo/setup-clojure@master
- with:
- tools-deps: '1.10.3.1029'
-
- - name: APT Update
- run: sudo apt-get update
-
- - name: Install Gnuplot
- run: sudo apt-get install gnuplot
-
- name: Install Blazectl
run: .github/scripts/install-blazectl.sh
@@ -613,8 +633,14 @@ jobs:
- name: Check Capability Statement
run: .github/scripts/check-capability-statement.sh
+ - name: Check Referential Integrity Enforced
+ run: .github/scripts/check-referential-integrity-enforced.sh
+
- name: Load Data
- run: blazectl --server http://localhost:8080/fhir upload .github/test-data
+ run: blazectl --server http://localhost:8080/fhir upload .github/test-data/synthea
+
+ - name: Check Total-Number of Resources are 92114
+ run: .github/scripts/check-total-number-of-resources.sh 92114
- name: Count Resources
run: blazectl --server http://localhost:8080/fhir count-resources
diff --git a/CHANGELOG.md b/CHANGELOG.md
index bdda7162b..5babd7402 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -1,5 +1,13 @@
# Changelog
+## v0.14.0
+
+### New Features
+
+* Allow Disabling Referential Integrity ([#544](https://github.com/samply/blaze/pull/544))
+
+The full changelog can be found [here](https://github.com/samply/blaze/milestone/11?closed=1).
+
## v0.13.5
### Bugfixes
diff --git a/docs/deployment/docker-deployment.md b/docs/deployment/docker-deployment.md
index 0ddb3113b..979f948ff 100644
--- a/docs/deployment/docker-deployment.md
+++ b/docs/deployment/docker-deployment.md
@@ -27,7 +27,7 @@ Blaze should log something like this:
2021-06-27T11:02:37.834Z ee086ef908c1 main INFO [blaze.core:64] - JVM version: 16.0.2
2021-06-27T11:02:37.834Z ee086ef908c1 main INFO [blaze.core:65] - Maximum available memory: 1738 MiB
2021-06-27T11:02:37.835Z ee086ef908c1 main INFO [blaze.core:66] - Number of available processors: 8
-2021-06-27T11:02:37.836Z ee086ef908c1 main INFO [blaze.core:67] - Successfully started Blaze version 0.13.5 in 8.2 seconds
+2021-06-27T11:02:37.836Z ee086ef908c1 main INFO [blaze.core:67] - Successfully started Blaze version 0.14.0 in 8.2 seconds
```
In order to test connectivity, query the health endpoint:
@@ -47,7 +47,7 @@ that should return:
```json
{
"name": "Blaze",
- "version": "0.13.5"
+ "version": "0.14.0"
}
```
diff --git a/docs/deployment/environment-variables.md b/docs/deployment/environment-variables.md
index b469d0f1d..ec820790f 100644
--- a/docs/deployment/environment-variables.md
+++ b/docs/deployment/environment-variables.md
@@ -80,6 +80,7 @@ More information about distributed deployment are available [here](distributed.m
| JAVA_TOOL_OPTIONS | — | | JVM options \(Docker only\) |
| FHIR_OPERATION_EVALUATE_MEASURE_THREADS | 4 | v0.8 | The maximum number of parallel $evaluate-measure executions. Not the same as the number of threads used for measure evaluation which equal to the number of available processors. |
| OPENID_PROVIDER_URL | - | v0.11 | [OpenID Connect][4] provider URL to enable [authentication][5] |
+| ENFORCE_REFERENTIAL_INTEGRITY | true | v0.14 | Enforce referential integrity on resource create, update and delete. It's enabled by default but can be disabled on proxy/middleware/secondary systems were a primary system ensures referential integrity. |
### Common JAVA_TOOL_OPTIONS
diff --git a/docs/deployment/manual-deployment.md b/docs/deployment/manual-deployment.md
index 3e18c6554..208afaeff 100644
--- a/docs/deployment/manual-deployment.md
+++ b/docs/deployment/manual-deployment.md
@@ -2,12 +2,12 @@
The installation works under Windows, Linux and macOS. The only dependency is an installed OpenJDK 11. Blaze is tested with [AdoptOpenJDK][1].
-Blaze runs on the JVM and comes as single JAR file. Download the most recent version [here](https://github.com/samply/blaze/releases/tag/v0.13.1). Look for `blaze-0.13.5-standalone.jar`.
+Blaze runs on the JVM and comes as single JAR file. Download the most recent version [here](https://github.com/samply/blaze/releases/tag/v0.13.1). Look for `blaze-0.14.0-standalone.jar`.
After the download, you can start blaze with the following command (Linux, macOS):
```sh
-java -jar blaze-0.13.5-standalone.jar -m blaze.core
+java -jar blaze-0.14.0-standalone.jar -m blaze.core
```
Blaze will run with an in-memory, volatile database for testing and demo purposes.
@@ -17,14 +17,14 @@ Blaze can be run with durable storage by setting the environment variables `STOR
Under Linux/macOS:
```sh
-STORAGE=standalone java -jar blaze-0.13.5-standalone.jar -m blaze.core
+STORAGE=standalone java -jar blaze-0.14.0-standalone.jar -m blaze.core
```
Under Windows, you need to set the Environment variables in the PowerShell before starting Blaze:
```powershell
$Env:STORAGE="standalone"
-java -jar blaze-0.13.5-standalone.jar -m blaze.core
+java -jar blaze-0.14.0-standalone.jar -m blaze.core
```
This will create three directories called `index`, `transaction` and `resource` inside the current working directory, one for each database part used.
@@ -42,7 +42,7 @@ The output should look like this:
2021-06-27T11:02:37.834Z ee086ef908c1 main INFO [blaze.core:64] - JVM version: 16.0.2
2021-06-27T11:02:37.834Z ee086ef908c1 main INFO [blaze.core:65] - Maximum available memory: 1738 MiB
2021-06-27T11:02:37.835Z ee086ef908c1 main INFO [blaze.core:66] - Number of available processors: 8
-2021-06-27T11:02:37.836Z ee086ef908c1 main INFO [blaze.core:67] - Successfully started Blaze version 0.13.5 in 8.2 seconds
+2021-06-27T11:02:37.836Z ee086ef908c1 main INFO [blaze.core:67] - Successfully started Blaze version 0.14.0 in 8.2 seconds
```
In order to test connectivity, query the health endpoint:
@@ -62,7 +62,7 @@ that should return:
```json
{
"name": "Blaze",
- "version": "0.13.5"
+ "version": "0.14.0"
}
```
diff --git a/docs/importing-data.md b/docs/importing-data.md
index d17b5c62e..f7ba1a632 100644
--- a/docs/importing-data.md
+++ b/docs/importing-data.md
@@ -1,6 +1,6 @@
# Importing Data
-In order to use Blaze for queries, you have to import your data. Although you can use the full functionality of the [FHIR RESTful API](https://www.hl7.org/fhir/http.html) available under `http://localhost:8080/fhir` to create resources, the easiest way is to download [blazectl](https://github.com/samply/blazectl/releases/tag/v0.2.0) to upload [bundles](https://www.hl7.org/fhir/bundle.html).
+In order to use Blaze for queries, you have to import your data. Although you can use the full functionality of the [FHIR RESTful API](https://www.hl7.org/fhir/http.html) available under `http://localhost:8080/fhir` to create resources, the easiest way is to download [blazectl](https://github.com/samply/blazectl/releases/tag/v0.8.1) to upload [bundles](https://www.hl7.org/fhir/bundle.html).
First you should test connectivity by counting already available resources in Blaze which should be zero:
@@ -71,3 +71,16 @@ Specimen : 100
total : 742
```
+## Disabling Referential Integrity Checks
+
+If your primary date source ensures referential integrity already, and you can't import the resources into Blaze in the right order or bunldes so that the referential integrity will be maintained per transaction, you can disable the referential integrity checks in Blaze by setting the env var `ENFORCE_REFERENTIAL_INTEGRITY` to `false`.
+
+The checks can be enabled/disabled at each start of Blaze. You can check whether the checks are enabled by executing:
+
+````sh
+curl -s http://localhost:8080/fhir/metadata | jq -r 'isempty(.rest[].resource[].referencePolicy[] | select(. == "enforced")) | not'
+````
+
+That command return `true` or `false` depending on whether the referential integrity checks are enabled or not.
+
+Please be aware that Blaze doesn't check the referential integrity of already imported resource if you enable the checks after you have already imported resources. By disabling the referential integrity checks at some time, you will have a database that can contain stale references.
diff --git a/modules/cql/src/blaze/elm/compiler/external_data.clj b/modules/cql/src/blaze/elm/compiler/external_data.clj
index 6e3fb1d79..6880d771c 100644
--- a/modules/cql/src/blaze/elm/compiler/external_data.clj
+++ b/modules/cql/src/blaze/elm/compiler/external_data.clj
@@ -4,14 +4,13 @@
Section numbers are according to
https://cql.hl7.org/04-logicalspecification.html."
(:require
- [blaze.anomaly :as ba :refer [throw-anom]]
+ [blaze.anomaly :as ba :refer [if-ok]]
[blaze.db.api :as d]
[blaze.db.api-spec]
[blaze.elm.compiler.core :as core]
[blaze.elm.spec]
[blaze.elm.util :as elm-util]
- [clojure.string :as str]
- [cognitect.anomalies :as anom]))
+ [clojure.string :as str]))
(set! *warn-on-reflection* true)
@@ -139,11 +138,10 @@
(if-let [result-type-name (:result-type-name (meta context-expr))]
(let [[value-type-ns context-type] (elm-util/parse-qualified-name result-type-name)]
(if (= "http://hl7.org/fhir" value-type-ns)
- (let [clauses [(into [code-property] (map code->clause-value) codes)]
- query (d/compile-compartment-query node context-type data-type clauses)]
- (if (::anom/category query)
- (throw (ex-info (::anom/message query) query))
- (->WithRelatedContextQueryRetrieveExpression context-expr query)))
+ (let [clauses [(into [code-property] (map code->clause-value) codes)]]
+ (if-ok [query (d/compile-compartment-query node context-type data-type clauses)]
+ (->WithRelatedContextQueryRetrieveExpression context-expr query)
+ ba/throw-anom))
(->WithRelatedContextCodeRetrieveExpression
context-expr data-type
@@ -159,13 +157,12 @@
(reify core/Expression
(-eval [_ {:keys [db]} _ _]
(into [] (d/type-list db data-type))))
- (let [clauses [(into [code-property] (map code->clause-value) codes)]
- query (d/compile-type-query node data-type clauses)]
- (if (::anom/category query)
- (throw (ex-info (::anom/message query) query))
+ (let [clauses [(into [code-property] (map code->clause-value) codes)]]
+ (if-ok [query (d/compile-type-query node data-type clauses)]
(reify core/Expression
(-eval [_ {:keys [db]} _ _]
- (into [] (d/execute-query db query))))))))
+ (into [] (d/execute-query db query))))
+ ba/throw-anom))))
(defn- expr* [node eval-context data-type code-property codes]
@@ -211,4 +208,4 @@
data-type
code-property
(some->> codes-expr (core/compile* context)))
- (throw-anom (unsupported-type-namespace-anom type-ns)))))
+ (ba/throw-anom (unsupported-type-namespace-anom type-ns)))))
diff --git a/modules/cql/src/blaze/elm/compiler/queries.clj b/modules/cql/src/blaze/elm/compiler/queries.clj
index 4379b8b25..8414a431e 100644
--- a/modules/cql/src/blaze/elm/compiler/queries.clj
+++ b/modules/cql/src/blaze/elm/compiler/queries.clj
@@ -335,6 +335,18 @@
(some #(when (contains? (:life/scopes %) alias) %) operands))
+(def ^:private missing-lhs-operand-anom
+ (ba/incorrect (format "Unsupported call without left-hand-side operand.")))
+
+
+(defn- missing-rhs-operand-msg [alias]
+ (format "Unsupported call without right-hand-side operand with alias `%s`."
+ alias))
+
+(defn- missing-rhs-operand-anom [alias]
+ (ba/incorrect (missing-rhs-operand-msg alias)))
+
+
(defn compile-with-equiv-clause
"We use the terms `lhs` and `rhs` for left-hand-side and right-hand-side of
the semi-join here.
@@ -355,12 +367,8 @@
(core/compile* (dissoc context :life/single-query-scope)))]
(->WithXformFactory rhs rhs-operand such-that lhs-operand
single-query-scope))
- (throw-anom
- (ba/incorrect
- (format "Unsupported call without left-hand-side operand."))))
- (throw-anom
- (ba/incorrect
- (format "Unsupported call without right-hand-side operand with alias `%s`." alias))))
+ (throw-anom missing-lhs-operand-anom))
+ (throw-anom (missing-rhs-operand-anom alias)))
(throw-anom
(ba/incorrect
(format "Unsupported call without single query scope.")))))
diff --git a/modules/cql/src/blaze/elm/deps_infer.clj b/modules/cql/src/blaze/elm/deps_infer.clj
index f16b3650d..f76abb8b0 100644
--- a/modules/cql/src/blaze/elm/deps_infer.clj
+++ b/modules/cql/src/blaze/elm/deps_infer.clj
@@ -2,7 +2,6 @@
(:require
[blaze.elm.spec]
[clojure.set :as set]
- [clojure.spec.alpha :as s]
[cuerdas.core :as str]))
@@ -19,9 +18,6 @@
(mapv #(update % :expression infer-deps) expression-defs))
-(s/fdef infer-library-deps
- :args (s/cat :library :elm/library))
-
(defn infer-library-deps [library]
(update-in library [:statements :def] update-expression-defs))
@@ -529,6 +525,12 @@
(derive :elm.deps.type/exists :elm.deps.type/unary-expression)
+;; 20.10. First
+(defmethod infer-deps :elm.deps.type/first
+ [expression]
+ (update expression :source infer-deps))
+
+
;; 20.25. SingletonFrom
(derive :elm.deps.type/singleton-from :elm.deps.type/unary-expression)
diff --git a/modules/cql/src/blaze/elm/equiv_relationships.clj b/modules/cql/src/blaze/elm/equiv_relationships.clj
index 28c4a8010..0c9efee08 100644
--- a/modules/cql/src/blaze/elm/equiv_relationships.clj
+++ b/modules/cql/src/blaze/elm/equiv_relationships.clj
@@ -3,7 +3,6 @@
expression resulting in equiv semi-joins and semi-differences."
(:require
[blaze.elm.spec]
- [clojure.spec.alpha :as s]
[cuerdas.core :as str]))
@@ -11,16 +10,13 @@
{:arglists '([expression])}
(fn [{:keys [type]}]
(assert type)
- (keyword "elm.normalizer.type" (str/kebab type))))
+ (keyword "elm.equiv-relationships.type" (str/kebab type))))
(defn- update-expression-defs [expression-defs]
(mapv #(update % :expression find-equiv-rels) expression-defs))
-(s/fdef find-equiv-rels-library
- :args (s/cat :library :elm/library))
-
(defn find-equiv-rels-library [library]
(update-in library [:statements :def] update-expression-defs))
@@ -30,12 +26,12 @@
expression)
-(defmethod find-equiv-rels :elm.normalizer.type/unary-expression
+(defmethod find-equiv-rels :elm.equiv-relationships.type/unary-expression
[expression]
(update expression :operand find-equiv-rels))
-(defmethod find-equiv-rels :elm.normalizer.type/multiary-expression
+(defmethod find-equiv-rels :elm.equiv-relationships.type/multiary-expression
[expression]
(update expression :operand #(mapv find-equiv-rels %)))
@@ -87,16 +83,31 @@
relationship)))
-(defmethod find-equiv-rels :elm.normalizer.type/query
+(defmethod find-equiv-rels :elm.equiv-relationships.type/query
[{relationships :relationship :as expression}]
(assoc expression :relationship (mapv find-equiv-relationship relationships)))
+
;; 20. List Operators
+;; 20.4. Distinct
+(derive :elm.equiv-relationships.type/distinct :elm.equiv-relationships.type/unary-expression)
+
+
;; 20.8. Exists
-(derive :elm.normalizer.type/exists :elm.normalizer.type/unary-expression)
+(derive :elm.equiv-relationships.type/exists :elm.equiv-relationships.type/unary-expression)
+
+
+;; 20.10. First
+(defmethod find-equiv-rels :elm.equiv-relationships.type/first
+ [expression]
+ (update expression :source find-equiv-rels))
+
+
+;; 20.11. Flatten
+(derive :elm.equiv-relationships.type/flatten :elm.equiv-relationships.type/unary-expression)
;; 20.25. SingletonFrom
-(derive :elm.normalizer.type/singleton-from :elm.normalizer.type/unary-expression)
+(derive :elm.equiv-relationships.type/singleton-from :elm.equiv-relationships.type/unary-expression)
diff --git a/modules/cql/src/blaze/elm/normalizer.clj b/modules/cql/src/blaze/elm/normalizer.clj
index cfd88bb86..37e300129 100644
--- a/modules/cql/src/blaze/elm/normalizer.clj
+++ b/modules/cql/src/blaze/elm/normalizer.clj
@@ -397,6 +397,30 @@
+;; 20. List Operators
+
+;; 20.4. Distinct
+(derive :elm.normalizer.type/distinct :elm.normalizer.type/unary-expression)
+
+;; 20.8. Exists
+(derive :elm.normalizer.type/exists :elm.normalizer.type/unary-expression)
+
+
+;; 20.10. First
+(defmethod normalize :elm.normalizer.type/first
+ [expression]
+ (update expression :source normalize))
+
+
+;; 20.11. Flatten
+(derive :elm.normalizer.type/flatten :elm.normalizer.type/unary-expression)
+
+
+;; 20.25. SingletonFrom
+(derive :elm.normalizer.type/singleton-from :elm.normalizer.type/unary-expression)
+
+
+
;; 23. Clinical Operators
;; 23.3. CalculateAge
diff --git a/modules/cql/test/blaze/elm/compiler/external_data_test.clj b/modules/cql/test/blaze/elm/compiler/external_data_test.clj
index 1d039c556..04709d2bc 100644
--- a/modules/cql/test/blaze/elm/compiler/external_data_test.clj
+++ b/modules/cql/test/blaze/elm/compiler/external_data_test.clj
@@ -224,17 +224,37 @@
{:def
[{:name "sys-def-225944"
:id "system-225806"}]}}}
- elm (elm/retrieve
- {:type "Medication"
- :codes #elm/list[#elm/code["sys-def-225944"
- "code-225809"]]})
+ elm #elm/retrieve
+ {:type "Medication"
+ :codes #elm/list[#elm/code["sys-def-225944"
+ "code-225809"]]}
expr (c/compile context elm)
db (d/db node)]
(given (core/-eval expr {:db db} nil nil)
count := 1
[0 fhir-spec/fhir-type] := :fhir/Medication
- [0 :id] := "0")))))
+ [0 :id] := "0"))))
+
+ (testing "unknown code property"
+ (with-system [{:blaze.db/keys [node]} mem-node-system]
+ (let [context
+ {:node node
+ :eval-context "Unfiltered"
+ :library
+ {:codeSystems
+ {:def
+ [{:name "sys-def-225944"
+ :id "system-225806"}]}}}
+ elm #elm/retrieve
+ {:type "Medication"
+ :codes #elm/list[#elm/code["sys-def-225944"
+ "code-225809"]]
+ :code-property "foo"}]
+
+ (given (ba/try-anomaly (c/compile context elm))
+ ::anom/category := ::anom/not-found
+ ::anom/message := "The search-param with code `foo` and type `Medication` was not found.")))))
(testing "with related context"
(testing "with pre-compiled database query"
@@ -245,13 +265,32 @@
{:def
[{:name "name-174207"
:resultTypeName "{http://hl7.org/fhir}Patient"}]}}
- elm {:type "Retrieve"
- :dataType "{http://hl7.org/fhir}Observation"
- :context #elm/expression-ref "name-174207"
- :codes #elm/list [#elm/code ["sys-def-174848" "code-174911"]]}
+ elm #elm/retrieve
+ {:type "Observation"
+ :context #elm/expression-ref "name-174207"
+ :codes #elm/list[#elm/code["sys-def-174848"
+ "code-174911"]]}
expr (c/compile {:node node :library library} elm)]
(given expr
- type := WithRelatedContextQueryRetrieveExpression)))))
+ type := WithRelatedContextQueryRetrieveExpression))))
+
+ (testing "unknown code property"
+ (with-system [{:blaze.db/keys [node]} mem-node-system]
+ (let [library {:codeSystems
+ {:def [{:name "sys-def-174848" :id "system-174915"}]}
+ :statements
+ {:def
+ [{:name "name-174207"
+ :resultTypeName "{http://hl7.org/fhir}Patient"}]}}
+ elm #elm/retrieve
+ {:type "Observation"
+ :context #elm/expression-ref "name-174207"
+ :codes #elm/list[#elm/code["sys-def-174848"
+ "code-174911"]]
+ :code-property "foo"}]
+ (given (ba/try-anomaly (c/compile {:node node :library library} elm))
+ ::anom/category := ::anom/not-found
+ ::anom/message := "The search-param with code `foo` and type `Observation` was not found.")))))
(testing "with unsupported type namespace"
(let [elm {:type "Retrieve" :dataType "{foo}Bar"}]
diff --git a/modules/cql/test/blaze/elm/compiler/list_operators_test.clj b/modules/cql/test/blaze/elm/compiler/list_operators_test.clj
index 71285fc49..29fc02a3b 100644
--- a/modules/cql/test/blaze/elm/compiler/list_operators_test.clj
+++ b/modules/cql/test/blaze/elm/compiler/list_operators_test.clj
@@ -165,7 +165,7 @@
;;
;; If the argument is null, the result is null.
(deftest compile-first-test
- (are [source res] (= res (core/-eval (c/compile {} {:type "First" :source source}) {} nil nil))
+ (are [source res] (= res (core/-eval (c/compile {} (elm/first source)) {} nil nil))
#elm/list [#elm/integer"1"] 1
#elm/list [#elm/integer"1" #elm/integer"2"] 1
diff --git a/modules/cql/test/blaze/elm/deps_infer_spec.clj b/modules/cql/test/blaze/elm/deps_infer_spec.clj
new file mode 100644
index 000000000..9d0332ce8
--- /dev/null
+++ b/modules/cql/test/blaze/elm/deps_infer_spec.clj
@@ -0,0 +1,9 @@
+(ns blaze.elm.deps-infer-spec
+ (:require
+ [blaze.elm.deps-infer :as deps-infer]
+ [blaze.elm.spec]
+ [clojure.spec.alpha :as s]))
+
+
+(s/fdef deps-infer/infer-library-deps
+ :args (s/cat :library :elm/library))
diff --git a/modules/cql/test/blaze/elm/equiv_relationships_spec.clj b/modules/cql/test/blaze/elm/equiv_relationships_spec.clj
new file mode 100644
index 000000000..221ef613e
--- /dev/null
+++ b/modules/cql/test/blaze/elm/equiv_relationships_spec.clj
@@ -0,0 +1,9 @@
+(ns blaze.elm.equiv-relationships-spec
+ (:require
+ [blaze.elm.equiv-relationships :as equiv-relationships]
+ [blaze.elm.spec]
+ [clojure.spec.alpha :as s]))
+
+
+(s/fdef equiv-relationships/find-equiv-rels-library
+ :args (s/cat :library :elm/library))
diff --git a/modules/cql/test/blaze/elm/equiv_relationships_test.clj b/modules/cql/test/blaze/elm/equiv_relationships_test.clj
index 5dcbe5f54..e1827f054 100644
--- a/modules/cql/test/blaze/elm/equiv_relationships_test.clj
+++ b/modules/cql/test/blaze/elm/equiv_relationships_test.clj
@@ -1,11 +1,11 @@
(ns blaze.elm.equiv-relationships-test
(:require
- [blaze.elm.equiv-relationships
- :refer [split-by-first-equal-expression]]
- [blaze.elm.literal]
+ [blaze.elm.equiv-relationships :as equiv-relationships]
+ [blaze.elm.equiv-relationships-spec]
+ [blaze.elm.literal :as elm]
[blaze.elm.literal-spec]
[clojure.spec.test.alpha :as st]
- [clojure.test :as test :refer [are deftest]]))
+ [clojure.test :as test :refer [are deftest is testing]]))
(st/instrument)
@@ -22,7 +22,7 @@
(deftest split-by-first-equal-expression-test
(are [input equal-expr rest-expr]
- (let [res (split-by-first-equal-expression input)]
+ (let [res (equiv-relationships/split-by-first-equal-expression input)]
(and (= equal-expr (:equal-expr res)) (= rest-expr (:rest-expr res))))
{:type "Equal"}
@@ -72,3 +72,61 @@
{:type "Equal" :pos 2}]}
{:type "Equal" :pos 1}
{:type "Equal" :pos 2}))
+
+
+(def query
+ {:type "Query"
+ :source
+ [{:expression
+ {:type "Retrieve"
+ :dataType "{http://hl7.org/fhir}Condition"}
+ :alias "C"}]
+ :relationship
+ [{:type "With"
+ :alias "P"
+ :expression
+ {:type "Retrieve" :dataType "{http://hl7.org/fhir}Procedure"}
+ :suchThat
+ {:type "Equal"
+ :operand [#elm/integer "1" #elm/integer "1"]}}]})
+
+
+(def equiv-query
+ {:type "Query"
+ :source
+ [{:expression
+ {:type "Retrieve"
+ :dataType "{http://hl7.org/fhir}Condition"}
+ :alias "C"}]
+ :relationship
+ [{:type "WithEquiv"
+ :alias "P"
+ :expression
+ {:type "Retrieve" :dataType "{http://hl7.org/fhir}Procedure"}
+ :equivOperand
+ [#elm/integer "1" #elm/integer "1"]}]})
+
+
+(deftest find-equiv-rels-test
+ (testing "query"
+ (is (= (equiv-relationships/find-equiv-rels query) equiv-query)))
+
+ (testing "20.4. Distinct"
+ (is (= (equiv-relationships/find-equiv-rels (elm/distinct query))
+ (elm/distinct equiv-query))))
+
+ (testing "20.8. Exists"
+ (is (= (equiv-relationships/find-equiv-rels (elm/exists query))
+ (elm/exists equiv-query))))
+
+ (testing "20.10. First"
+ (is (= (equiv-relationships/find-equiv-rels (elm/first query))
+ (elm/first equiv-query))))
+
+ (testing "20.11. Flatten"
+ (is (= (equiv-relationships/find-equiv-rels (elm/flatten query))
+ (elm/flatten equiv-query))))
+
+ (testing "20.25. SingletonFrom"
+ (is (= (equiv-relationships/find-equiv-rels (elm/singleton-from query))
+ (elm/singleton-from equiv-query)))))
diff --git a/modules/cql/test/blaze/elm/literal.clj b/modules/cql/test/blaze/elm/literal.clj
index 358d71ef4..eadc830cc 100644
--- a/modules/cql/test/blaze/elm/literal.clj
+++ b/modules/cql/test/blaze/elm/literal.clj
@@ -1,6 +1,6 @@
(ns blaze.elm.literal
(:refer-clojure
- :exclude [and boolean count distinct flatten list max min not or time])
+ :exclude [and boolean count distinct first flatten list max min not or time])
(:require
[blaze.elm.spec]
[clojure.spec.alpha :as s]
@@ -102,12 +102,16 @@
;; 11. External Data
;; 11.1. Retrieve
-(defn retrieve [{:keys [type codes]}]
+(defn retrieve [{:keys [type codes code-property context]}]
(cond->
{:type "Retrieve"
:dataType (str "{http://hl7.org/fhir}" type)}
codes
- (assoc :codes codes)))
+ (assoc :codes codes)
+ code-property
+ (assoc :codeProperty code-property)
+ context
+ (assoc :context context)))
@@ -528,6 +532,11 @@
{:type "Exists" :operand list})
+;; 20.10. First
+(defn first [source]
+ {:type "First" :source source})
+
+
;; 20.11. Flatten
(defn flatten [list]
{:type "Flatten" :operand list})
diff --git a/modules/cql/test/blaze/elm/literal_spec.clj b/modules/cql/test/blaze/elm/literal_spec.clj
index 621121cb9..84d84fa42 100644
--- a/modules/cql/test/blaze/elm/literal_spec.clj
+++ b/modules/cql/test/blaze/elm/literal_spec.clj
@@ -366,6 +366,12 @@
:ret :elm/expression)
+;; 20.10. First
+(s/fdef literal/first
+ :args (s/cat :source :elm/expression)
+ :ret :elm/expression)
+
+
;; 20.11. Flatten
(s/fdef literal/flatten
:args (s/cat :list :elm/expression)
diff --git a/modules/cql/test/blaze/elm/normalizer_test.clj b/modules/cql/test/blaze/elm/normalizer_test.clj
index a6209dd76..b768545d8 100644
--- a/modules/cql/test/blaze/elm/normalizer_test.clj
+++ b/modules/cql/test/blaze/elm/normalizer_test.clj
@@ -2,7 +2,7 @@
"Section numbers are according to
https://cql.hl7.org/04-logicalspecification.html."
(:require
- [blaze.elm.literal]
+ [blaze.elm.literal :as elm]
[blaze.elm.normalizer :refer [normalize]]
[blaze.elm.normalizer-spec]
[clojure.spec.test.alpha :as st]
@@ -242,3 +242,36 @@
:condition := (normalize expression-1)
:then := (normalize expression-2)
:else := (normalize expression-3))))
+
+
+
+;; 20. List Operators
+
+;; 20.4. Distinct
+(deftest normalize-distinct-test
+ (given (normalize (elm/distinct expression-1))
+ :operand := (normalize expression-1)))
+
+
+;; 20.8. Exists
+(deftest normalize-exists-test
+ (given (normalize (elm/exists expression-1))
+ :operand := (normalize expression-1)))
+
+
+;; 20.10. First
+(deftest normalize-first-test
+ (given (normalize (elm/first expression-1))
+ :source := (normalize expression-1)))
+
+
+;; 20.11. Flatten
+(deftest normalize-flatten-test
+ (given (normalize (elm/flatten expression-1))
+ :operand := (normalize expression-1)))
+
+
+;; 20.25. SingletonFrom
+(deftest normalize-singleton-from-test
+ (given (normalize (elm/singleton-from expression-1))
+ :operand := (normalize expression-1)))
diff --git a/modules/cql/test/data_readers.clj b/modules/cql/test/data_readers.clj
index db40e8c3e..0c537430a 100644
--- a/modules/cql/test/data_readers.clj
+++ b/modules/cql/test/data_readers.clj
@@ -9,6 +9,7 @@
elm/quantity blaze.elm.literal/quantity
elm/parameter-ref blaze.elm.literal/parameter-ref
elm/expression-ref blaze.elm.literal/expression-ref
+ elm/retrieve blaze.elm.literal/retrieve
elm/equal blaze.elm.literal/equal
elm/equivalent blaze.elm.literal/equivalent
elm/greater blaze.elm.literal/greater
@@ -50,6 +51,9 @@
elm/interval blaze.elm.literal/interval
elm/intersect blaze.elm.literal/intersect
elm/current blaze.elm.literal/current
+ elm/distinct blaze.elm.literal/distinct
+ elm/exists blaze.elm.literal/exists
+ elm/first blaze.elm.literal/first
elm/singleton-from blaze.elm.literal/singleton-from
elm/as blaze.elm.literal/as
elm/can-convert-quantity blaze.elm.literal/can-convert-quantity
diff --git a/modules/db-resource-store-cassandra/src/blaze/db/resource_store/cassandra.clj b/modules/db-resource-store-cassandra/src/blaze/db/resource_store/cassandra.clj
index afce51de0..564154e7d 100644
--- a/modules/db-resource-store-cassandra/src/blaze/db/resource_store/cassandra.clj
+++ b/modules/db-resource-store-cassandra/src/blaze/db/resource_store/cassandra.clj
@@ -166,7 +166,7 @@
::cass/request-timeout]))
-(defn init-msg [config]
+(defn- init-msg [config]
(str "Open Cassandra resource store with the following settings: "
(cass/format-config config)))
diff --git a/modules/db-stub/src/blaze/db/api_stub.clj b/modules/db-stub/src/blaze/db/api_stub.clj
index c02635605..8667d84ed 100644
--- a/modules/db-stub/src/blaze/db/api_stub.clj
+++ b/modules/db-stub/src/blaze/db/api_stub.clj
@@ -19,16 +19,18 @@
[java-time :as time]))
-(def mem-node-system
+(defn create-mem-node-system [node-config]
{:blaze.db/node
- {:tx-log (ig/ref :blaze.db/tx-log)
- :resource-handle-cache (ig/ref :blaze.db/resource-handle-cache)
- :tx-cache (ig/ref :blaze.db/tx-cache)
- :indexer-executor (ig/ref :blaze.db.node/indexer-executor)
- :resource-store (ig/ref :blaze.db/resource-store)
- :kv-store (ig/ref :blaze.db/index-kv-store)
- :search-param-registry (ig/ref :blaze.db/search-param-registry)
- :poll-timeout (time/millis 10)}
+ (merge
+ {:tx-log (ig/ref :blaze.db/tx-log)
+ :resource-handle-cache (ig/ref :blaze.db/resource-handle-cache)
+ :tx-cache (ig/ref :blaze.db/tx-cache)
+ :indexer-executor (ig/ref :blaze.db.node/indexer-executor)
+ :resource-store (ig/ref :blaze.db/resource-store)
+ :kv-store (ig/ref :blaze.db/index-kv-store)
+ :search-param-registry (ig/ref :blaze.db/search-param-registry)
+ :poll-timeout (time/millis 10)}
+ node-config)
::tx-log/local
{:kv-store (ig/ref :blaze.db/transaction-kv-store)
@@ -70,6 +72,10 @@
:blaze.db/search-param-registry {}})
+(def mem-node-system
+ (create-mem-node-system {}))
+
+
(defmacro with-system-data [[binding-form system] txs & body]
`(with-system [system# ~system]
(run! #(deref (d/transact (:blaze.db/node system#) %)) ~txs)
diff --git a/modules/db-tx-log/src/blaze/db/tx_log/spec.clj b/modules/db-tx-log/src/blaze/db/tx_log/spec.clj
index 4d712d574..a28c434e4 100644
--- a/modules/db-tx-log/src/blaze/db/tx_log/spec.clj
+++ b/modules/db-tx-log/src/blaze/db/tx_log/spec.clj
@@ -23,12 +23,8 @@
:fhir.type/name)
-(s/def :blaze.db/local-ref
- (s/tuple :fhir.type/name :blaze.resource/id))
-
-
(s/def :blaze.db.tx-cmd/refs
- (s/coll-of :blaze.db/local-ref))
+ (s/coll-of :blaze.fhir/local-ref-tuple))
(s/def :blaze.db/t
diff --git a/modules/db/src/blaze/db/node.clj b/modules/db/src/blaze/db/node.clj
index 4d3139482..57e9200d0 100644
--- a/modules/db/src/blaze/db/node.clj
+++ b/modules/db/src/blaze/db/node.clj
@@ -232,7 +232,7 @@
(rs/get resource-store hash)))
-(defrecord Node [tx-log rh-cache tx-cache kv-store resource-store
+(defrecord Node [context tx-log rh-cache tx-cache kv-store resource-store
search-param-registry resource-indexer state run? poll-timeout
finished]
np/Node
@@ -252,7 +252,7 @@
(-submit-tx [_ tx-ops]
(log/trace "submit" (count tx-ops) "tx-ops")
(if-ok [_ (validation/validate-ops tx-ops)]
- (let [[tx-cmds entries] (tx/prepare-ops tx-ops)]
+ (let [[tx-cmds entries] (tx/prepare-ops context tx-ops)]
(-> (rs/put! resource-store entries)
(ac/then-compose (fn [_] (tx-log/submit tx-log tx-cmds entries)))))
ac/completed-future))
@@ -358,6 +358,20 @@
:error-t 0})
+(defn- init-msg
+ [{:keys [enforce-referential-integrity]
+ :or {enforce-referential-integrity true}}]
+ (log/info "Open local database node with"
+ (if enforce-referential-integrity "enabled" "disabled")
+ "referential integrity checks"))
+
+
+(defn- ctx
+ [{:keys [enforce-referential-integrity]
+ :or {enforce-referential-integrity true}}]
+ {:blaze.db/enforce-referential-integrity enforce-referential-integrity})
+
+
(defmethod ig/pre-init-spec :blaze.db/node [_]
(s/keys
:req-un
@@ -367,16 +381,18 @@
::indexer-executor
:blaze.db/kv-store
:blaze.db/resource-store
- :blaze.db/search-param-registry]))
-
+ :blaze.db/search-param-registry]
+ :opt-un
+ [:blaze.db/enforce-referential-integrity]))
(defmethod ig/init-key :blaze.db/node
[_ {:keys [tx-log resource-handle-cache tx-cache indexer-executor kv-store
resource-store search-param-registry poll-timeout]
- :or {poll-timeout (time/seconds 1)}}]
- (log/info "Open local database node")
+ :or {poll-timeout (time/seconds 1)}
+ :as config}]
+ (init-msg config)
(let [resource-indexer (new-resource-indexer search-param-registry kv-store)
- node (->Node tx-log resource-handle-cache tx-cache kv-store
+ node (->Node (ctx config) tx-log resource-handle-cache tx-cache kv-store
resource-store search-param-registry resource-indexer
(atom (initial-state kv-store))
(volatile! true)
diff --git a/modules/db/src/blaze/db/node/transaction.clj b/modules/db/src/blaze/db/node/transaction.clj
index b5e4013a5..97f2aada4 100644
--- a/modules/db/src/blaze/db/node/transaction.clj
+++ b/modules/db/src/blaze/db/node/transaction.clj
@@ -10,13 +10,13 @@
[blaze.fhir.spec.type :as type]))
-(defmulti prepare-op first)
+(defmulti prepare-op (fn [_ [op]] op))
(defmethod prepare-op :create
- [[op resource clauses]]
+ [{:keys [references-fn]} [op resource clauses]]
(let [hash (hash/generate resource)
- refs (type/references resource)]
+ refs (references-fn resource)]
{:hash-resource
[hash resource]
:blaze.db/tx-cmd
@@ -32,9 +32,9 @@
(defmethod prepare-op :put
- [[op resource matches]]
+ [{:keys [references-fn]} [op resource matches]]
(let [hash (hash/generate resource)
- refs (type/references resource)]
+ refs (references-fn resource)]
{:hash-resource
[hash resource]
:blaze.db/tx-cmd
@@ -50,7 +50,7 @@
(defmethod prepare-op :delete
- [[_ type id]]
+ [_ [_ type id]]
{:blaze.db/tx-cmd
{:op "delete"
:type type
@@ -61,11 +61,24 @@
(juxt #(mapv :blaze.db/tx-cmd %) #(into {} (map :hash-resource) %)))
+(defn- ctx
+ [{:blaze.db/keys [enforce-referential-integrity]
+ :or {enforce-referential-integrity true}}]
+ {:references-fn
+ (if enforce-referential-integrity
+ type/references
+ (constantly nil))})
+
+
(defn prepare-ops
"Splits `tx-ops` into a tuple of :blaze.db/tx-cmds and a map of resource
- hashes to resource contents."
- [tx-ops]
- (split (mapv prepare-op tx-ops)))
+ hashes to resource contents.
+
+ Puts :refs into the returned :blaze.db/tx-cmds if
+ :blaze.db/enforce-referential-integrity is true in `context` which is the
+ default."
+ [context tx-ops]
+ (split (mapv (partial prepare-op (ctx context)) tx-ops)))
(defn- missing-tx-msg [t]
diff --git a/modules/db/src/blaze/db/spec.clj b/modules/db/src/blaze/db/spec.clj
index 05d1f90a7..071bb1cd4 100644
--- a/modules/db/src/blaze/db/spec.clj
+++ b/modules/db/src/blaze/db/spec.clj
@@ -90,3 +90,7 @@
(s/def :blaze.db/tx-ops
(s/coll-of :blaze.db/tx-op :kind vector? :min-count 1))
+
+
+(s/def :blaze.db/enforce-referential-integrity
+ boolean?)
diff --git a/modules/db/test/blaze/db/api_test.clj b/modules/db/test/blaze/db/api_test.clj
index fe2313b01..50f67a548 100644
--- a/modules/db/test/blaze/db/api_test.clj
+++ b/modules/db/test/blaze/db/api_test.clj
@@ -52,16 +52,18 @@
(test/use-fixtures :each fixture)
-(def system
+(defn create-system [node-config]
{:blaze.db/node
- {:tx-log (ig/ref :blaze.db/tx-log)
- :resource-handle-cache (ig/ref :blaze.db/resource-handle-cache)
- :tx-cache (ig/ref :blaze.db/tx-cache)
- :indexer-executor (ig/ref :blaze.db.node/indexer-executor)
- :resource-store (ig/ref :blaze.db/resource-store)
- :kv-store (ig/ref :blaze.db/index-kv-store)
- :search-param-registry (ig/ref :blaze.db/search-param-registry)
- :poll-timeout (time/millis 10)}
+ (merge
+ {:tx-log (ig/ref :blaze.db/tx-log)
+ :resource-handle-cache (ig/ref :blaze.db/resource-handle-cache)
+ :tx-cache (ig/ref :blaze.db/tx-cache)
+ :indexer-executor (ig/ref :blaze.db.node/indexer-executor)
+ :resource-store (ig/ref :blaze.db/resource-store)
+ :kv-store (ig/ref :blaze.db/index-kv-store)
+ :search-param-registry (ig/ref :blaze.db/search-param-registry)
+ :poll-timeout (time/millis 10)}
+ node-config)
::tx-log/local
{:kv-store (ig/ref :blaze.db/transaction-kv-store)
@@ -103,6 +105,10 @@
:blaze.db/search-param-registry {}})
+(def system
+ (create-system {}))
+
+
(defmethod ig/init-key ::slow-resource-store [_ {:keys [resource-store]}]
(reify
rs/ResourceStore
@@ -197,7 +203,7 @@
(with-system [{:blaze.db/keys [node]} system]
@(d/transact
node
- ;; the create ops are purposely disordered in order to test the
+ ;; create ops are purposely disordered in order to test the
;; reference dependency ordering algorithm
[[:create
{:fhir/type :fhir/Observation :id "0"
@@ -514,6 +520,23 @@
::anom/category := ::anom/conflict
::anom/message := "Referential integrity violated. Resource `Observation/1` should be deleted but is referenced from `List/0`."))))
+ (testing "not enforcing referential integrity"
+ (testing "creating an Observation were the subject doesn't exist"
+ (testing "create"
+ (with-system [{:blaze.db/keys [node]} (create-system {:enforce-referential-integrity false})]
+ @(d/transact
+ node
+ [[:create
+ {:fhir/type :fhir/Observation :id "0"
+ :subject #fhir/Reference{:reference "Patient/0"}}]])
+
+ (given @(d/pull node (d/resource-handle (d/db node) "Observation" "0"))
+ :fhir/type := :fhir/Observation
+ :id := "0"
+ [:subject :reference] := "Patient/0"
+ [:meta :versionId] := #fhir/id"1"
+ [meta :blaze.db/op] := :create)))))
+
(testing "creating 100 transactions in parallel"
(with-system [{:blaze.db/keys [node]} slow-resource-store-system]
(let [db-futures
diff --git a/modules/db/test/blaze/db/node/transaction/spec.clj b/modules/db/test/blaze/db/node/transaction/spec.clj
new file mode 100644
index 000000000..186834294
--- /dev/null
+++ b/modules/db/test/blaze/db/node/transaction/spec.clj
@@ -0,0 +1,11 @@
+(ns blaze.db.node.transaction.spec
+ (:require
+ [blaze.db.spec]
+ [blaze.db.tx-log.spec]
+ [blaze.fhir.hash.spec]
+ [blaze.fhir.spec.spec]
+ [clojure.spec.alpha :as s]))
+
+
+(s/def :blaze.db.node.transaction/context
+ (s/keys :opt [:blaze.db/enforce-referential-integrity]))
diff --git a/modules/db/test/blaze/db/node/transaction_spec.clj b/modules/db/test/blaze/db/node/transaction_spec.clj
index 2de2bdeba..e6f05b528 100644
--- a/modules/db/test/blaze/db/node/transaction_spec.clj
+++ b/modules/db/test/blaze/db/node/transaction_spec.clj
@@ -2,12 +2,10 @@
(:require
[blaze.anomaly-spec]
[blaze.db.node.transaction :as tx]
- [blaze.db.tx-log.spec]
- [blaze.fhir.hash.spec]
- [blaze.fhir.spec.spec]
+ [blaze.db.node.transaction.spec]
[clojure.spec.alpha :as s]))
(s/fdef tx/prepare-ops
- :args (s/cat :tx-ops :blaze.db/tx-ops)
+ :args (s/cat :context :blaze.db.node.transaction/context :tx-ops :blaze.db/tx-ops)
:ret (s/tuple :blaze.db/tx-cmds (s/map-of :blaze.resource/hash :blaze/resource)))
diff --git a/modules/db/test/blaze/db/node/transaction_test.clj b/modules/db/test/blaze/db/node/transaction_test.clj
index ecaabf6ef..9f390e017 100644
--- a/modules/db/test/blaze/db/node/transaction_test.clj
+++ b/modules/db/test/blaze/db/node/transaction_test.clj
@@ -23,10 +23,15 @@
(test/use-fixtures :each fixture)
+(def context
+ {})
+
+
(deftest prepare-ops-test
(testing "create"
(testing "with references"
(given (tx/prepare-ops
+ context
[[:create {:fhir/type :fhir/Observation :id "0"
:subject #fhir/Reference{:reference "Patient/0"}}]])
[0 0 :op] := "create"
@@ -36,10 +41,18 @@
[0 0 :refs] := [["Patient" "0"]]
[1 0 0] := #blaze/byte-string"7B3980C2BFCF43A8CDD61662E1AABDA9CA6431964820BC8D52958AEC9A270378"
[1 0 1] := {:fhir/type :fhir/Observation :id "0"
- :subject #fhir/Reference{:reference "Patient/0"}}))
+ :subject #fhir/Reference{:reference "Patient/0"}})
+
+ (testing "with disabled referential integrity check"
+ (given (tx/prepare-ops
+ {:blaze.db/enforce-referential-integrity false}
+ [[:create {:fhir/type :fhir/Observation :id "0"
+ :subject #fhir/Reference{:reference "Patient/0"}}]])
+ [0 0 :refs] :? empty?)))
(testing "conditional"
(given (tx/prepare-ops
+ context
[[:create {:fhir/type :fhir/Patient :id "id-220036"}
[["identifier" "115508"]]]])
[0 0 :op] := "create"
@@ -47,21 +60,41 @@
[0 0 :id] := "id-220036"
[0 0 :if-none-exist] := [["identifier" "115508"]])))
- (testing "one put"
- (given (tx/prepare-ops [[:put {:fhir/type :fhir/Patient :id "0"}]])
+ (testing "put"
+ (given (tx/prepare-ops context [[:put {:fhir/type :fhir/Patient :id "0"}]])
[0 0 :op] := "put"
[0 0 :type] := "Patient"
[0 0 :id] := "0"
[0 0 :hash] := #blaze/byte-string"C9ADE22457D5AD750735B6B166E3CE8D6878D09B64C2C2868DCB6DE4C9EFBD4F"
[1 0 0] := #blaze/byte-string"C9ADE22457D5AD750735B6B166E3CE8D6878D09B64C2C2868DCB6DE4C9EFBD4F"
- [1 0 1] := {:fhir/type :fhir/Patient :id "0"}))
+ [1 0 1] := {:fhir/type :fhir/Patient :id "0"})
+
+ (testing "with references"
+ (given (tx/prepare-ops
+ context
+ [[:put {:fhir/type :fhir/Observation :id "0"
+ :subject #fhir/Reference{:reference "Patient/0"}}]])
+ [0 0 :op] := "put"
+ [0 0 :type] := "Observation"
+ [0 0 :id] := "0"
+ [0 0 :hash] := #blaze/byte-string"7B3980C2BFCF43A8CDD61662E1AABDA9CA6431964820BC8D52958AEC9A270378"
+ [0 0 :refs] := [["Patient" "0"]]
+ [1 0 0] := #blaze/byte-string"7B3980C2BFCF43A8CDD61662E1AABDA9CA6431964820BC8D52958AEC9A270378"
+ [1 0 1] := {:fhir/type :fhir/Observation :id "0"
+ :subject #fhir/Reference{:reference "Patient/0"}})
+
+ (testing "with disabled referential integrity check"
+ (given (tx/prepare-ops {:blaze.db/enforce-referential-integrity false}
+ [[:put {:fhir/type :fhir/Observation :id "0"
+ :subject #fhir/Reference{:reference "Patient/0"}}]])
+ [0 0 :refs] :? empty?)))
- (testing "one put with matches"
- (given (tx/prepare-ops [[:put {:fhir/type :fhir/Patient :id "0"} 4]])
- [0 0 :if-match] := 4))
+ (testing "with matches"
+ (given (tx/prepare-ops context [[:put {:fhir/type :fhir/Patient :id "0"} 4]])
+ [0 0 :if-match] := 4)))
- (testing "one delete"
- (given (tx/prepare-ops [[:delete "Patient" "0"]])
+ (testing "delete"
+ (given (tx/prepare-ops context [[:delete "Patient" "0"]])
[0 0 :op] := "delete"
[0 0 :type] := "Patient"
[0 0 :id] := "0"
diff --git a/modules/db/test/blaze/db/node_test.clj b/modules/db/test/blaze/db/node_test.clj
index e81212422..b5293d0ff 100644
--- a/modules/db/test/blaze/db/node_test.clj
+++ b/modules/db/test/blaze/db/node_test.clj
@@ -144,7 +144,21 @@
[:explain ::s/problems 4 :pred] := `(fn ~'[%] (contains? ~'% :resource-store))
[:explain ::s/problems 5 :pred] := `(fn ~'[%] (contains? ~'% :search-param-registry))
[:explain ::s/problems 6 :pred] := `(fn ~'[%] (satisfies? tx-log/TxLog ~'%))
- [:explain ::s/problems 6 :val] := ::invalid)))
+ [:explain ::s/problems 6 :val] := ::invalid))
+
+ (testing "invalid enforce-referential-integrity"
+ (given-thrown (ig/init {:blaze.db/node {:enforce-referential-integrity ::invalid}})
+ :key := :blaze.db/node
+ :reason := ::ig/build-failed-spec
+ [:explain ::s/problems 0 :pred] := `(fn ~'[%] (contains? ~'% :tx-log))
+ [:explain ::s/problems 1 :pred] := `(fn ~'[%] (contains? ~'% :resource-handle-cache))
+ [:explain ::s/problems 2 :pred] := `(fn ~'[%] (contains? ~'% :tx-cache))
+ [:explain ::s/problems 3 :pred] := `(fn ~'[%] (contains? ~'% :indexer-executor))
+ [:explain ::s/problems 4 :pred] := `(fn ~'[%] (contains? ~'% :kv-store))
+ [:explain ::s/problems 5 :pred] := `(fn ~'[%] (contains? ~'% :resource-store))
+ [:explain ::s/problems 6 :pred] := `(fn ~'[%] (contains? ~'% :search-param-registry))
+ [:explain ::s/problems 7 :pred] := `boolean?
+ [:explain ::s/problems 7 :val] := ::invalid)))
(deftest duration-seconds-collector-init-test
diff --git a/modules/fhir-structure/src/blaze/fhir/spec/spec.clj b/modules/fhir-structure/src/blaze/fhir/spec/spec.clj
index 23276a9c8..f70236664 100644
--- a/modules/fhir-structure/src/blaze/fhir/spec/spec.clj
+++ b/modules/fhir-structure/src/blaze/fhir/spec/spec.clj
@@ -25,10 +25,14 @@
(s/and string? #(re-matches #"[A-Za-z0-9\-\.]{1,64}" %)))
+(s/def :blaze.fhir/local-ref-tuple
+ (s/tuple :fhir.resource/type :blaze.resource/id))
+
+
(s/def :blaze.fhir/local-ref
(s/and string?
(s/conformer #(str/split % #"/" 2))
- (s/tuple :fhir.resource/type :blaze.resource/id)))
+ :blaze.fhir/local-ref-tuple))
(s/def :blaze/resource
diff --git a/modules/fhir-structure/src/blaze/fhir/spec/type.clj b/modules/fhir-structure/src/blaze/fhir/spec/type.clj
index f7cb0f076..abc1db941 100644
--- a/modules/fhir-structure/src/blaze/fhir/spec/type.clj
+++ b/modules/fhir-structure/src/blaze/fhir/spec/type.clj
@@ -55,7 +55,10 @@
(p/-hash-into x sink))
-(defn references [x]
+(defn references
+ "Returns a collection of local references which are tuples of FHIR resource
+ type name and FHIR resource id."
+ [x]
(p/-references x))
diff --git a/modules/fhir-structure/src/blaze/fhir/spec/type_spec.clj b/modules/fhir-structure/src/blaze/fhir/spec/type_spec.clj
index 978266468..5d8ab69e2 100644
--- a/modules/fhir-structure/src/blaze/fhir/spec/type_spec.clj
+++ b/modules/fhir-structure/src/blaze/fhir/spec/type_spec.clj
@@ -19,7 +19,7 @@
(s/fdef type/references
:args (s/cat :x any?)
- :ret (s/coll-of :blaze.db/local-ref))
+ :ret (s/coll-of :blaze.fhir/local-ref-tuple))
(s/fdef type/->Date
diff --git a/modules/interaction/.clj-kondo/config.edn b/modules/interaction/.clj-kondo/config.edn
index 21883cafd..bef83071e 100644
--- a/modules/interaction/.clj-kondo/config.edn
+++ b/modules/interaction/.clj-kondo/config.edn
@@ -24,7 +24,8 @@
blaze.interaction.transaction-test/with-handler clojure.core/fn
blaze.interaction.transaction-test/with-handler-data clojure.core/fn
blaze.interaction.update-test/with-handler clojure.core/fn
- blaze.interaction.update-test/with-handler-data clojure.core/fn}
+ blaze.interaction.update-test/with-handler-data clojure.core/fn
+ blaze.test-util/with-system clojure.core/with-open}
:linters
{:unsorted-required-namespaces
diff --git a/modules/interaction/test/blaze/interaction/create_test.clj b/modules/interaction/test/blaze/interaction/create_test.clj
index 23e00def5..4ae5eefee 100644
--- a/modules/interaction/test/blaze/interaction/create_test.clj
+++ b/modules/interaction/test/blaze/interaction/create_test.clj
@@ -6,14 +6,15 @@
https://www.hl7.org/fhir/http.html#ops"
(:require
[blaze.anomaly-spec]
- [blaze.db.api-stub :refer [mem-node-system with-system-data]]
+ [blaze.db.api-stub
+ :refer [create-mem-node-system with-system-data]]
[blaze.executors :as ex]
[blaze.fhir.response.create-spec]
[blaze.fhir.spec.type]
[blaze.interaction.create]
[blaze.interaction.util-spec]
[blaze.middleware.fhir.error :refer [wrap-error]]
- [blaze.test-util :refer [given-thrown]]
+ [blaze.test-util :refer [given-thrown with-system]]
[clojure.spec.alpha :as s]
[clojure.spec.test.alpha :as st]
[clojure.test :as test :refer [deftest is testing]]
@@ -43,7 +44,8 @@
(def router
(reitit/router
- [["/Patient" {:name :Patient/type}]]
+ [["/Patient" {:name :Patient/type}]
+ ["/Observation" {:name :Observation/type}]]
{:syntax :bracket}))
@@ -74,8 +76,8 @@
[:explain ::s/problems 3 :val] := ::invalid)))
-(def system
- (assoc mem-node-system
+(defn create-system [node-config]
+ (assoc (create-mem-node-system node-config)
:blaze.interaction/create
{:node (ig/ref :blaze.db/node)
:executor (ig/ref :blaze.test/executor)
@@ -85,6 +87,10 @@
:blaze.test/fixed-rng-fn {}))
+(def system
+ (create-system {}))
+
+
(defn wrap-defaults [handler]
(fn [request]
(handler
@@ -104,59 +110,63 @@
(reitit/map->Match {:data {:fhir.resource/type "Patient"}}))
+(def observation-match
+ (reitit/map->Match {:data {:fhir.resource/type "Observation"}}))
+
+
(deftest handler-test
- (testing "Returns Error on missing body"
- (with-handler [handler]
- []
- (let [{:keys [status body]}
- @(handler
- {::reitit/match patient-match})]
+ (testing "errors on"
+ (testing "missing body"
+ (with-handler [handler]
+ []
+ (let [{:keys [status body]}
+ @(handler
+ {::reitit/match patient-match})]
- (is (= 400 status))
+ (is (= 400 status))
- (given body
- :fhir/type := :fhir/OperationOutcome
- [:issue 0 :severity] := #fhir/code"error"
- [:issue 0 :code] := #fhir/code"invalid"
- [:issue 0 :diagnostics] := "Missing HTTP body."))))
+ (given body
+ :fhir/type := :fhir/OperationOutcome
+ [:issue 0 :severity] := #fhir/code"error"
+ [:issue 0 :code] := #fhir/code"invalid"
+ [:issue 0 :diagnostics] := "Missing HTTP body."))))
- (testing "Returns Error on type mismatch"
- (with-handler [handler]
- []
- (let [{:keys [status body]}
- @(handler
- {::reitit/match patient-match
- :body {:fhir/type :fhir/Observation}})]
+ (testing "type mismatch"
+ (with-handler [handler]
+ []
+ (let [{:keys [status body]}
+ @(handler
+ {::reitit/match patient-match
+ :body {:fhir/type :fhir/Observation}})]
- (is (= 400 status))
+ (is (= 400 status))
- (given body
- :fhir/type := :fhir/OperationOutcome
- [:issue 0 :severity] := #fhir/code"error"
- [:issue 0 :code] := #fhir/code"invariant"
- [:issue 0 :details :coding 0 :system] := #fhir/uri"http://terminology.hl7.org/CodeSystem/operation-outcome"
- [:issue 0 :details :coding 0 :code] := #fhir/code"MSG_RESOURCE_TYPE_MISMATCH"
- [:issue 0 :diagnostics] := "Resource type `Observation` doesn't match the endpoint type `Patient`."))))
-
- (testing "Returns Error violated referential integrity"
- (with-handler [handler]
- []
- (let [{:keys [status body]}
- @(handler
- {::reitit/match {:data {:fhir.resource/type "Observation"}}
- :body {:fhir/type :fhir/Observation :id "0"
- :subject #fhir/Reference{:reference "Patient/0"}}})]
+ (given body
+ :fhir/type := :fhir/OperationOutcome
+ [:issue 0 :severity] := #fhir/code"error"
+ [:issue 0 :code] := #fhir/code"invariant"
+ [:issue 0 :details :coding 0 :system] := #fhir/uri"http://terminology.hl7.org/CodeSystem/operation-outcome"
+ [:issue 0 :details :coding 0 :code] := #fhir/code"MSG_RESOURCE_TYPE_MISMATCH"
+ [:issue 0 :diagnostics] := "Resource type `Observation` doesn't match the endpoint type `Patient`."))))
+
+ (testing "violated referential integrity"
+ (with-handler [handler]
+ []
+ (let [{:keys [status body]}
+ @(handler
+ {::reitit/match observation-match
+ :body {:fhir/type :fhir/Observation :id "0"
+ :subject #fhir/Reference{:reference "Patient/0"}}})]
- (is (= 409 status))
+ (is (= 409 status))
- (given body
- :fhir/type := :fhir/OperationOutcome
- [:issue 0 :severity] := #fhir/code"error"
- [:issue 0 :code] := #fhir/code"conflict"
- [:issue 0 :diagnostics] :=
- "Referential integrity violated. Resource `Patient/0` doesn't exist."))))
+ (given body
+ :fhir/type := :fhir/OperationOutcome
+ [:issue 0 :severity] := #fhir/code"error"
+ [:issue 0 :code] := #fhir/code"conflict"
+ [:issue 0 :diagnostics] := "Referential integrity violated. Resource `Patient/0` doesn't exist.")))))
- (testing "On newly created resource"
+ (testing "on newly created resource"
(testing "with no Prefer header"
(with-handler [handler]
[]
@@ -328,4 +338,32 @@
:fhir/type := :fhir/OperationOutcome
[:issue 0 :severity] := #fhir/code"error"
[:issue 0 :code] := #fhir/code"conflict"
- [:issue 0 :diagnostics] := "Conditional create of a Patient with query `birthdate=2020` failed because at least the two matches `Patient/0/_history/1` and `Patient/1/_history/1` were found.")))))))
+ [:issue 0 :diagnostics] := "Conditional create of a Patient with query `birthdate=2020` failed because at least the two matches `Patient/0/_history/1` and `Patient/1/_history/1` were found."))))))
+
+ (testing "with disabled referential integrity check"
+ (with-system [{handler :blaze.interaction/create} (create-system {:enforce-referential-integrity false})]
+ (let [{:keys [status headers body]}
+ @((-> handler wrap-defaults wrap-error)
+ {::reitit/match observation-match
+ :body {:fhir/type :fhir/Observation :id "0"
+ :subject #fhir/Reference{:reference "Patient/0"}}})]
+
+ (is (= 201 status))
+
+ (testing "Location header"
+ (is (= (str base-url "/Observation/AAAAAAAAAAAAAAAA/_history/1")
+ (get headers "Location"))))
+
+ (testing "Transaction time in Last-Modified header"
+ (is (= "Thu, 1 Jan 1970 00:00:00 GMT" (get headers "Last-Modified"))))
+
+ (testing "Version in ETag header"
+ ;; 1 is the T of the transaction of the resource creation
+ (is (= "W/\"1\"" (get headers "ETag"))))
+
+ (given body
+ :fhir/type := :fhir/Observation
+ :id := "AAAAAAAAAAAAAAAA"
+ [:meta :versionId] := #fhir/id"1"
+ [:meta :lastUpdated] := Instant/EPOCH
+ [:subject :reference] := "Patient/0")))))
diff --git a/modules/interaction/test/blaze/interaction/update_test.clj b/modules/interaction/test/blaze/interaction/update_test.clj
index 09a1018f6..25f211408 100644
--- a/modules/interaction/test/blaze/interaction/update_test.clj
+++ b/modules/interaction/test/blaze/interaction/update_test.clj
@@ -6,13 +6,14 @@
https://www.hl7.org/fhir/http.html#ops"
(:require
[blaze.anomaly-spec]
- [blaze.db.api-stub :refer [mem-node-system with-system-data]]
+ [blaze.db.api-stub
+ :refer [create-mem-node-system with-system-data]]
[blaze.executors :as ex]
[blaze.fhir.response.create-spec]
[blaze.fhir.spec.type]
[blaze.interaction.update]
[blaze.middleware.fhir.error :refer [wrap-error]]
- [blaze.test-util :refer [given-thrown]]
+ [blaze.test-util :refer [given-thrown with-system]]
[clojure.spec.alpha :as s]
[clojure.spec.test.alpha :as st]
[clojure.test :as test :refer [deftest is testing]]
@@ -42,7 +43,8 @@
(def router
(reitit/router
- [["/Patient" {:name :Patient/type}]]
+ [["/Patient" {:name :Patient/type}]
+ ["/Observation" {:name :Observation/type}]]
{:syntax :bracket}))
@@ -54,6 +56,10 @@
(reitit/map->Match {:data {:fhir.resource/type "Patient"}}))
+(def observation-match
+ (reitit/map->Match {:data {:fhir.resource/type "Observation"}}))
+
+
(deftest init-test
(testing "nil config"
(given-thrown (ig/init {:blaze.interaction/update nil})
@@ -77,14 +83,18 @@
[:explain ::s/problems 1 :val] := ::invalid)))
-(def system
- (assoc mem-node-system
+(defn create-system [node-config]
+ (assoc (create-mem-node-system node-config)
:blaze.interaction/update
{:node (ig/ref :blaze.db/node)
:executor (ig/ref :blaze.test/executor)}
:blaze.test/executor {}))
+(def system
+ (create-system {}))
+
+
(defn wrap-defaults [handler]
(fn [request]
(handler
@@ -101,123 +111,123 @@
(deftest handler-test
- (testing "on missing body"
- (with-handler [handler]
- []
- (let [{:keys [status body]}
- @(handler
- {:path-params {:id "0"}
- ::reitit/match patient-match})]
+ (testing "erros on"
+ (testing "missing body"
+ (with-handler [handler]
+ []
+ (let [{:keys [status body]}
+ @(handler
+ {:path-params {:id "0"}
+ ::reitit/match patient-match})]
- (testing "returns error"
- (is (= 400 status))
+ (testing "returns error"
+ (is (= 400 status))
- (given body
- :fhir/type := :fhir/OperationOutcome
- [:issue 0 :severity] := #fhir/code"error"
- [:issue 0 :code] := #fhir/code"invalid"
- [:issue 0 :diagnostics] := "Missing HTTP body.")))))
-
- (testing "on type mismatch"
- (with-handler [handler]
- []
- (let [{:keys [status body]}
- @(handler
- {:path-params {:id "0"}
- ::reitit/match patient-match
- :body {:fhir/type :fhir/Observation}})]
+ (given body
+ :fhir/type := :fhir/OperationOutcome
+ [:issue 0 :severity] := #fhir/code"error"
+ [:issue 0 :code] := #fhir/code"invalid"
+ [:issue 0 :diagnostics] := "Missing HTTP body.")))))
- (testing "returns error"
- (is (= 400 status))
+ (testing "type mismatch"
+ (with-handler [handler]
+ []
+ (let [{:keys [status body]}
+ @(handler
+ {:path-params {:id "0"}
+ ::reitit/match patient-match
+ :body {:fhir/type :fhir/Observation}})]
- (given body
- :fhir/type := :fhir/OperationOutcome
- [:issue 0 :severity] := #fhir/code"error"
- [:issue 0 :code] := #fhir/code"invariant"
- [:issue 0 :details :coding 0 :system] := operation-outcome
- [:issue 0 :details :coding 0 :code] := #fhir/code"MSG_RESOURCE_TYPE_MISMATCH"
- [:issue 0 :diagnostics] := "Invalid update interaction of a Observation at a Patient endpoint.")))))
-
- (testing "on missing id"
- (with-handler [handler]
- []
- (let [{:keys [status body]}
- @(handler
- {:path-params {:id "0"}
- ::reitit/match patient-match
- :body {:fhir/type :fhir/Patient}})]
+ (testing "returns error"
+ (is (= 400 status))
- (testing "returns error"
- (is (= 400 status))
+ (given body
+ :fhir/type := :fhir/OperationOutcome
+ [:issue 0 :severity] := #fhir/code"error"
+ [:issue 0 :code] := #fhir/code"invariant"
+ [:issue 0 :details :coding 0 :system] := operation-outcome
+ [:issue 0 :details :coding 0 :code] := #fhir/code"MSG_RESOURCE_TYPE_MISMATCH"
+ [:issue 0 :diagnostics] := "Invalid update interaction of a Observation at a Patient endpoint.")))))
+
+ (testing "missing id"
+ (with-handler [handler]
+ []
+ (let [{:keys [status body]}
+ @(handler
+ {:path-params {:id "0"}
+ ::reitit/match patient-match
+ :body {:fhir/type :fhir/Patient}})]
- (given body
- :fhir/type := :fhir/OperationOutcome
- [:issue 0 :severity] := #fhir/code"error"
- [:issue 0 :code] := #fhir/code"required"
- [:issue 0 :details :coding 0 :system] := operation-outcome
- [:issue 0 :details :coding 0 :code] := #fhir/code"MSG_RESOURCE_ID_MISSING"
- [:issue 0 :diagnostics] := "Missing resource id.")))))
-
-
- (testing "on ID mismatch"
- (with-handler [handler]
- []
- (let [{:keys [status body]}
- @(handler
- {:path-params {:id "0"}
- ::reitit/match patient-match
- :body {:fhir/type :fhir/Patient :id "1"}})]
+ (testing "returns error"
+ (is (= 400 status))
+
+ (given body
+ :fhir/type := :fhir/OperationOutcome
+ [:issue 0 :severity] := #fhir/code"error"
+ [:issue 0 :code] := #fhir/code"required"
+ [:issue 0 :details :coding 0 :system] := operation-outcome
+ [:issue 0 :details :coding 0 :code] := #fhir/code"MSG_RESOURCE_ID_MISSING"
+ [:issue 0 :diagnostics] := "Missing resource id.")))))
+
+ (testing "ID mismatch"
+ (with-handler [handler]
+ []
+ (let [{:keys [status body]}
+ @(handler
+ {:path-params {:id "0"}
+ ::reitit/match patient-match
+ :body {:fhir/type :fhir/Patient :id "1"}})]
- (testing "returns error"
- (is (= 400 status))
+ (testing "returns error"
+ (is (= 400 status))
- (given body
- :fhir/type := :fhir/OperationOutcome
- [:issue 0 :severity] := #fhir/code"error"
- [:issue 0 :code] := #fhir/code"invariant"
- [:issue 0 :details :coding 0 :system] := operation-outcome
- [:issue 0 :details :coding 0 :code] := #fhir/code"MSG_RESOURCE_ID_MISMATCH"
- [:issue 0 :diagnostics] := "The resource id `1` doesn't match the endpoints id `0`.")))))
-
- (testing "on optimistic locking failure"
- (with-handler [handler]
- [[[:create {:fhir/type :fhir/Patient :id "0"}]]
- [[:put {:fhir/type :fhir/Patient :id "0"}]]]
-
- (let [{:keys [status body]}
- @(handler
- {:path-params {:id "0"}
- ::reitit/match patient-match
- :headers {"if-match" "W/\"1\""}
- :body {:fhir/type :fhir/Patient :id "0"}})]
+ (given body
+ :fhir/type := :fhir/OperationOutcome
+ [:issue 0 :severity] := #fhir/code"error"
+ [:issue 0 :code] := #fhir/code"invariant"
+ [:issue 0 :details :coding 0 :system] := operation-outcome
+ [:issue 0 :details :coding 0 :code] := #fhir/code"MSG_RESOURCE_ID_MISMATCH"
+ [:issue 0 :diagnostics] := "The resource id `1` doesn't match the endpoints id `0`.")))))
+
+ (testing "optimistic locking failure"
+ (with-handler [handler]
+ [[[:create {:fhir/type :fhir/Patient :id "0"}]]
+ [[:put {:fhir/type :fhir/Patient :id "0"}]]]
- (testing "returns error"
- (is (= 412 status))
+ (let [{:keys [status body]}
+ @(handler
+ {:path-params {:id "0"}
+ ::reitit/match patient-match
+ :headers {"if-match" "W/\"1\""}
+ :body {:fhir/type :fhir/Patient :id "0"}})]
- (given body
- :fhir/type := :fhir/OperationOutcome
- [:issue 0 :severity] := #fhir/code"error"
- [:issue 0 :code] := #fhir/code"conflict"
- [:issue 0 :diagnostics] := "Precondition `W/\"1\"` failed on `Patient/0`.")))))
-
- (testing "on violated referential integrity"
- (with-handler [handler]
- []
- (let [{:keys [status body]}
- @(handler
- {:path-params {:id "0"}
- ::reitit/match {:data {:fhir.resource/type "Observation"}}
- :body {:fhir/type :fhir/Observation :id "0"
- :subject #fhir/Reference{:reference "Patient/0"}}})]
+ (testing "returns error"
+ (is (= 412 status))
- (testing "returns error"
- (is (= 409 status))
+ (given body
+ :fhir/type := :fhir/OperationOutcome
+ [:issue 0 :severity] := #fhir/code"error"
+ [:issue 0 :code] := #fhir/code"conflict"
+ [:issue 0 :diagnostics] := "Precondition `W/\"1\"` failed on `Patient/0`.")))))
- (given body
- :fhir/type := :fhir/OperationOutcome
- [:issue 0 :severity] := #fhir/code"error"
- [:issue 0 :code] := #fhir/code"conflict"
- [:issue 0 :diagnostics] := "Referential integrity violated. Resource `Patient/0` doesn't exist.")))))
+ (testing "violated referential integrity"
+ (with-handler [handler]
+ []
+ (let [{:keys [status body]}
+ @(handler
+ {:path-params {:id "0"}
+ ::reitit/match observation-match
+ :body {:fhir/type :fhir/Observation :id "0"
+ :subject #fhir/Reference{:reference "Patient/0"}}})]
+
+ (testing "returns error"
+ (is (= 409 status))
+
+ (given body
+ :fhir/type := :fhir/OperationOutcome
+ [:issue 0 :severity] := #fhir/code"error"
+ [:issue 0 :code] := #fhir/code"conflict"
+ [:issue 0 :diagnostics] := "Referential integrity violated. Resource `Patient/0` doesn't exist."))))))
(testing "on newly created resource"
(testing "with no Prefer header"
@@ -371,4 +381,35 @@
:id := "0"
:birthDate := #fhir/date"2020"
[:meta :versionId] := #fhir/id"2"
- [:meta :lastUpdated] := Instant/EPOCH)))))))
+ [:meta :lastUpdated] := Instant/EPOCH))))))
+
+ (testing "with disabled referential integrity check"
+ (with-system [{handler :blaze.interaction/update} (create-system {:enforce-referential-integrity false})]
+ (let [{:keys [status headers body]}
+ @((-> handler wrap-defaults wrap-error)
+ {:path-params {:id "0"}
+ ::reitit/match observation-match
+ :body {:fhir/type :fhir/Observation :id "0"
+ :subject #fhir/Reference{:reference "Patient/0"}}})]
+
+ (testing "Returns 201"
+ (is (= 201 status)))
+
+ (testing "Location header"
+ (is (= "base-url-134013/Observation/0/_history/1" (get headers "Location"))))
+
+ (testing "Transaction time in Last-Modified header"
+ (is (= "Thu, 1 Jan 1970 00:00:00 GMT" (get headers "Last-Modified"))))
+
+ (testing "VersionId in ETag header"
+ (is (= "W/\"1\"" (get headers "ETag"))))
+
+ (testing "Location header"
+ (is (= "base-url-134013/Observation/0/_history/1" (get headers "Location"))))
+
+ (testing "Contains the resource as body"
+ (given body
+ :fhir/type := :fhir/Observation
+ :id := "0"
+ [:meta :versionId] := #fhir/id"1"
+ [:meta :lastUpdated] := Instant/EPOCH))))))
diff --git a/modules/page-store-cassandra/src/blaze/page_store/cassandra.clj b/modules/page-store-cassandra/src/blaze/page_store/cassandra.clj
index 5d96c54e0..de083315c 100644
--- a/modules/page-store-cassandra/src/blaze/page_store/cassandra.clj
+++ b/modules/page-store-cassandra/src/blaze/page_store/cassandra.clj
@@ -116,7 +116,7 @@
::cass/request-timeout]))
-(defn init-msg [config]
+(defn- init-msg [config]
(str "Open Cassandra page store with the following settings: "
(cass/format-config config)))
diff --git a/modules/rest-api/src/blaze/rest_api.clj b/modules/rest-api/src/blaze/rest_api.clj
index 79a7acc89..255bb6dee 100644
--- a/modules/rest-api/src/blaze/rest_api.clj
+++ b/modules/rest-api/src/blaze/rest_api.clj
@@ -2,6 +2,7 @@
(:require
[blaze.async.comp :as ac]
[blaze.db.search-param-registry.spec]
+ [blaze.db.spec]
[blaze.executors :as ex]
[blaze.handler.util :as handler-util]
[blaze.middleware.fhir.error :refer [wrap-error]]
@@ -111,18 +112,19 @@
[:blaze.rest-api.json-parse/executor]
:req-un
[:blaze/base-url
- ::version
+ :blaze/version
:blaze.rest-api/structure-definitions
:blaze.db/node
:blaze.db/search-param-registry]
:opt-un
- [::context-path
+ [:blaze/context-path
::auth-backends
::search-system-handler
::transaction-handler
::history-system-handler
::resource-patterns
- ::operations]))
+ ::operations
+ :blaze.db/enforce-referential-integrity]))
(defmethod ig/init-key :blaze/rest-api
diff --git a/modules/rest-api/src/blaze/rest_api/capabilities.clj b/modules/rest-api/src/blaze/rest_api/capabilities.clj
index faa104d23..55cbab276 100644
--- a/modules/rest-api/src/blaze/rest_api/capabilities.clj
+++ b/modules/rest-api/src/blaze/rest_api/capabilities.clj
@@ -17,8 +17,10 @@
(defn- capability-resource
- {:arglists '([resource-patterns operations search-param-registry structure-definition])}
- [resource-patterns operations search-param-registry
+ {:arglists '([context structure-definition])}
+ [{:keys [resource-patterns operations search-param-registry
+ enforce-referential-integrity]
+ :or {enforce-referential-integrity true}}
{:keys [name] :as structure-definition}]
(when-let
[{:blaze.rest-api.resource-pattern/keys [interactions]}
@@ -58,9 +60,11 @@
:conditionalUpdate false
:conditionalDelete #fhir/code"not-supported"
:referencePolicy
- [#fhir/code"literal"
- #fhir/code"enforced"
+ (cond->
+ [#fhir/code"literal"
#fhir/code"local"]
+ enforce-referential-integrity
+ (conj #fhir/code"enforced"))
:searchParam
(transduce
(map
@@ -89,17 +93,16 @@
(defn capabilities-handler
+ {:arglists '([context])}
[{:keys
[version
context-path
structure-definitions
- search-param-registry
search-system-handler
transaction-handler
- history-system-handler
- resource-patterns
- operations]
- :or {context-path ""}}]
+ history-system-handler]
+ :or {context-path ""}
+ :as context}]
(let [capability-statement
{:fhir/type :fhir/CapabilityStatement
:status #fhir/code"active"
@@ -108,7 +111,7 @@
:copyright
#fhir/markdown"Copyright 2019 - 2021 The Samply Community\n\nLicensed under the Apache License, Version 2.0 (the \"License\"); you may not use this file except in compliance with the License. You may obtain a copy of the License at\n\nhttp://www.apache.org/licenses/LICENSE-2.0\n\nUnless required by applicable law or agreed to in writing, software distributed under the License is distributed on an \"AS IS\" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License."
:kind #fhir/code"instance"
- :date #fhir/dateTime"2021-12-02"
+ :date #fhir/dateTime"2021-12-03"
:software
{:name "Blaze"
:version version}
@@ -125,7 +128,7 @@
[]
(comp
u/structure-definition-filter
- (keep #(capability-resource resource-patterns operations search-param-registry %)))
+ (keep (partial capability-resource context)))
structure-definitions)
:interaction
(cond-> []
diff --git a/modules/rest-api/src/blaze/rest_api/spec.clj b/modules/rest-api/src/blaze/rest_api/spec.clj
index b0094f53d..68cc7270c 100644
--- a/modules/rest-api/src/blaze/rest_api/spec.clj
+++ b/modules/rest-api/src/blaze/rest_api/spec.clj
@@ -94,14 +94,6 @@
(s/coll-of :blaze.rest-api/compartment))
-(s/def :blaze.rest-api/version
- string?)
-
-
-(s/def :blaze.rest-api/context-path
- string?)
-
-
(s/def :blaze.rest-api.operation/code
string?)
diff --git a/modules/rest-api/test/blaze/rest_api/capabilities/spec.clj b/modules/rest-api/test/blaze/rest_api/capabilities/spec.clj
new file mode 100644
index 000000000..ed96c0e53
--- /dev/null
+++ b/modules/rest-api/test/blaze/rest_api/capabilities/spec.clj
@@ -0,0 +1,17 @@
+(ns blaze.rest-api.capabilities.spec
+ (:require
+ [blaze.db.search-param-registry.spec]
+ [blaze.rest-api.spec]
+ [blaze.spec]
+ [clojure.spec.alpha :as s]))
+
+
+(s/def :blaze.rest-api.capabilities/context
+ (s/keys
+ :req-un
+ [:blaze/version
+ :blaze.rest-api/structure-definitions
+ :blaze.db/search-param-registry]
+ :opt-un
+ [:blaze/context-path
+ :blaze.db/enforce-referential-integrity]))
diff --git a/modules/rest-api/test/blaze/rest_api/capabilities_spec.clj b/modules/rest-api/test/blaze/rest_api/capabilities_spec.clj
new file mode 100644
index 000000000..831b56fe1
--- /dev/null
+++ b/modules/rest-api/test/blaze/rest_api/capabilities_spec.clj
@@ -0,0 +1,9 @@
+(ns blaze.rest-api.capabilities-spec
+ (:require
+ [blaze.rest-api.capabilities :as capabilities]
+ [blaze.rest-api.capabilities.spec]
+ [clojure.spec.alpha :as s]))
+
+
+(s/fdef capabilities/capabilities-handler
+ :args (s/cat :context ::capabilities/context))
diff --git a/modules/rest-api/test/blaze/rest_api/capabilities_test.clj b/modules/rest-api/test/blaze/rest_api/capabilities_test.clj
index 0e860c06f..71ef5a5a8 100644
--- a/modules/rest-api/test/blaze/rest_api/capabilities_test.clj
+++ b/modules/rest-api/test/blaze/rest_api/capabilities_test.clj
@@ -3,6 +3,7 @@
[blaze.db.impl.search-param]
[blaze.db.search-param-registry :as sr]
[blaze.rest-api.capabilities :as capabilities]
+ [blaze.rest-api.capabilities-spec]
[clojure.spec.test.alpha :as st]
[clojure.test :as test :refer [deftest testing]]
[juxt.iota :refer [given]]
@@ -99,7 +100,30 @@
:body)
:fhir/type := :fhir/CapabilityStatement
[:rest 0 :resource 0 :type] := #fhir/code"Patient"
- [:rest 0 :resource 0 :interaction 0 :code] := #fhir/code"read"))
+ [:rest 0 :resource 0 :interaction 0 :code] := #fhir/code"read"
+ [:rest 0 :resource 0 :referencePolicy] :? (partial some #{#fhir/code"enforced"}))
+
+ (testing "with disabled referential integrity check"
+ (given
+ (-> @((capabilities/capabilities-handler
+ {:version "version-131640"
+ :structure-definitions
+ [{:kind "resource" :name "Patient"}]
+ :search-param-registry search-param-registry
+ :resource-patterns
+ [#:blaze.rest-api.resource-pattern
+ {:type "Patient"
+ :interactions
+ {:read
+ #:blaze.rest-api.interaction
+ {:handler (fn [_])}}}]
+ :enforce-referential-integrity false})
+ {})
+ :body)
+ :fhir/type := :fhir/CapabilityStatement
+ [:rest 0 :resource 0 :type] := #fhir/code"Patient"
+ [:rest 0 :resource 0 :interaction 0 :code] := #fhir/code"read"
+ [:rest 0 :resource 0 :referencePolicy] :? (comp not (partial some #{#fhir/code"enforced"})))))
(testing "Observation interaction"
(given
diff --git a/modules/rest-api/test/blaze/rest_api_test.clj b/modules/rest-api/test/blaze/rest_api_test.clj
index 810e72353..8fc7c066f 100644
--- a/modules/rest-api/test/blaze/rest_api_test.clj
+++ b/modules/rest-api/test/blaze/rest_api_test.clj
@@ -267,7 +267,20 @@
[:explain ::s/problems 2 :pred] := `(fn ~'[%] (contains? ~'% :version))
[:explain ::s/problems 3 :pred] := `(fn ~'[%] (contains? ~'% :structure-definitions))
[:explain ::s/problems 4 :pred] := `(fn ~'[%] (contains? ~'% :node))
- [:explain ::s/problems 5 :pred] := `(fn ~'[%] (contains? ~'% :search-param-registry)))))
+ [:explain ::s/problems 5 :pred] := `(fn ~'[%] (contains? ~'% :search-param-registry))))
+
+ (testing "invalid enforce-referential-integrity"
+ (given-thrown (ig/init {:blaze/rest-api {:enforce-referential-integrity ::invalid}})
+ :key := :blaze/rest-api
+ :reason := ::ig/build-failed-spec
+ [:explain ::s/problems 0 :pred] := `(fn ~'[%] (contains? ~'% :blaze.rest-api.json-parse/executor))
+ [:explain ::s/problems 1 :pred] := `(fn ~'[%] (contains? ~'% :base-url))
+ [:explain ::s/problems 2 :pred] := `(fn ~'[%] (contains? ~'% :version))
+ [:explain ::s/problems 3 :pred] := `(fn ~'[%] (contains? ~'% :structure-definitions))
+ [:explain ::s/problems 4 :pred] := `(fn ~'[%] (contains? ~'% :node))
+ [:explain ::s/problems 5 :pred] := `(fn ~'[%] (contains? ~'% :search-param-registry))
+ [:explain ::s/problems 6 :pred] := `boolean?
+ [:explain ::s/problems 6 :val] := ::invalid)))
(def system
diff --git a/modules/spec/src/blaze/spec.clj b/modules/spec/src/blaze/spec.clj
index dfc0d9abd..7bb193ae4 100644
--- a/modules/spec/src/blaze/spec.clj
+++ b/modules/spec/src/blaze/spec.clj
@@ -11,6 +11,10 @@
(s/and string? (complement #(str/ends-with? % "/"))))
+(s/def :blaze/version
+ string?)
+
+
(s/def :blaze/context-path
(s/and
string?
diff --git a/perf-test/gatling/pom.xml b/perf-test/gatling/pom.xml
index 05eab9395..636c77bda 100644
--- a/perf-test/gatling/pom.xml
+++ b/perf-test/gatling/pom.xml
@@ -5,7 +5,7 @@
samply.blaze
gatling
- 0.13.5
+ 0.14.0
1.8
diff --git a/pom.xml b/pom.xml
index 8d38b736f..f83ee2929 100644
--- a/pom.xml
+++ b/pom.xml
@@ -3,7 +3,7 @@
4.0.0
samply
blaze
- 0.13.5
+ 0.14.0
blaze
A FHIR Store with internal, fast CQL Evaluation Engine
diff --git a/resources/blaze.edn b/resources/blaze.edn
index fea7e2a7b..848ef7439 100644
--- a/resources/blaze.edn
+++ b/resources/blaze.edn
@@ -69,7 +69,8 @@
:def-uri "http://hl7.org/fhir/OperationDefinition/Measure-evaluate-measure"
:resource-types ["Measure"]
:type-handler #blaze/ref :blaze.fhir.operation.evaluate-measure/handler
- :instance-handler #blaze/ref :blaze.fhir.operation.evaluate-measure/handler}]}
+ :instance-handler #blaze/ref :blaze.fhir.operation.evaluate-measure/handler}]
+ :enforce-referential-integrity #blaze/cfg ["ENFORCE_REFERENTIAL_INTEGRITY" boolean? true]}
;;
;; FHIR Interactions
@@ -178,7 +179,8 @@
:indexer-executor #blaze/ref :blaze.db.node/indexer-executor
:resource-store #blaze/ref :blaze.db/resource-cache
:kv-store #blaze/ref :blaze.db/index-kv-store
- :search-param-registry #blaze/ref :blaze.db/search-param-registry}
+ :search-param-registry #blaze/ref :blaze.db/search-param-registry
+ :enforce-referential-integrity #blaze/cfg ["ENFORCE_REFERENTIAL_INTEGRITY" boolean? true]}
:blaze.db.node/indexer-executor {}
diff --git a/src/blaze/system.clj b/src/blaze/system.clj
index 97120c2d6..67c9b6ffd 100644
--- a/src/blaze/system.clj
+++ b/src/blaze/system.clj
@@ -87,7 +87,7 @@
(def ^:private root-config
- {:blaze/version "0.13.5"
+ {:blaze/version "0.14.0"
:blaze/clock {}