From cca0b633a830d1a031f1347b105962fdeca73959 Mon Sep 17 00:00:00 2001 From: James Agnew Date: Fri, 27 Jan 2023 07:02:00 -0500 Subject: [PATCH 1/9] One more fix for #4467 (#4469) --- .../server/provider/HashMapResourceProvider.java | 11 +++++------ .../server/provider/HashMapResourceProviderTest.java | 12 +++++++++++- 2 files changed, 16 insertions(+), 7 deletions(-) diff --git a/hapi-fhir-server/src/main/java/ca/uhn/fhir/rest/server/provider/HashMapResourceProvider.java b/hapi-fhir-server/src/main/java/ca/uhn/fhir/rest/server/provider/HashMapResourceProvider.java index ce3b17905a4..045147d5aa0 100644 --- a/hapi-fhir-server/src/main/java/ca/uhn/fhir/rest/server/provider/HashMapResourceProvider.java +++ b/hapi-fhir-server/src/main/java/ca/uhn/fhir/rest/server/provider/HashMapResourceProvider.java @@ -264,17 +264,16 @@ public class HashMapResourceProvider implements IResour if (!versions.containsKey(versionId)) { throw new ResourceNotFoundException(Msg.code(1982) + theId); } else { - T resource = versions.get(versionId); - if (resource == null || ResourceMetadataKeyEnum.DELETED_AT.get(resource) != null) { - throw new ResourceGoneException(Msg.code(1983) + theId); - } - retVal = resource; + retVal = versions.get(versionId); } - } else { retVal = versions.lastEntry().getValue(); } + if (retVal == null || ResourceMetadataKeyEnum.DELETED_AT.get(retVal) != null) { + throw new ResourceGoneException(Msg.code(1983) + theId); + } + myReadCount.incrementAndGet(); retVal = fireInterceptorsAndFilterAsNeeded(retVal, theRequestDetails); diff --git a/hapi-fhir-structures-r4/src/test/java/ca/uhn/fhir/rest/server/provider/HashMapResourceProviderTest.java b/hapi-fhir-structures-r4/src/test/java/ca/uhn/fhir/rest/server/provider/HashMapResourceProviderTest.java index 526ef9dab6b..3bfbf90c7a7 100644 --- a/hapi-fhir-structures-r4/src/test/java/ca/uhn/fhir/rest/server/provider/HashMapResourceProviderTest.java +++ b/hapi-fhir-structures-r4/src/test/java/ca/uhn/fhir/rest/server/provider/HashMapResourceProviderTest.java @@ -115,8 +115,10 @@ public class HashMapResourceProviderTest { assertEquals(1, myPatientResourceProvider.getCountDelete()); - // Read + // VRead original version ourRestServer.getFhirClient().read().resource("Patient").withId(id.withVersion("1")).execute(); + + // Vread gone version try { ourRestServer.getFhirClient().read().resource("Patient").withId(id.withVersion("2")).execute(); fail(); @@ -124,6 +126,14 @@ public class HashMapResourceProviderTest { // good } + // Read (non vread) gone version + try { + ourRestServer.getFhirClient().read().resource("Patient").withId(id.toUnqualifiedVersionless()).execute(); + fail(); + } catch (ResourceGoneException e) { + // good + } + // History should include deleted entry Bundle history = ourRestServer.getFhirClient().history().onType(Patient.class).returnBundle(Bundle.class).execute(); ourLog.info("History:\n{}", ourCtx.newJsonParser().setPrettyPrint(true).encodeResourceToString(history)); From 6eeb328ec64b5b92b780eba07c4a49a6f3b8efc6 Mon Sep 17 00:00:00 2001 From: James Agnew Date: Fri, 27 Jan 2023 12:31:11 -0500 Subject: [PATCH 2/9] Update IPS credits (#4474) --- .../src/main/resources/ca/uhn/hapi/fhir/docs/server_jpa/ips.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/hapi-fhir-docs/src/main/resources/ca/uhn/hapi/fhir/docs/server_jpa/ips.md b/hapi-fhir-docs/src/main/resources/ca/uhn/hapi/fhir/docs/server_jpa/ips.md index 67cfe65c68b..5f718d1c635 100644 --- a/hapi-fhir-docs/src/main/resources/ca/uhn/hapi/fhir/docs/server_jpa/ips.md +++ b/hapi-fhir-docs/src/main/resources/ca/uhn/hapi/fhir/docs/server_jpa/ips.md @@ -60,4 +60,4 @@ Built-in Narrative Templates: # Credits -This module is based on the excellent work of Rio Bennin and Panayiotis Savva of the University of Cyprus. +This module is based on the excellent work of Rio Bennin of Crossroads Labs, and Panayiotis Savva and Constantinos Yiasemi of the University of Cyprus. From 54c9b9422ade12246bee8ee6c3d7912ca99aba26 Mon Sep 17 00:00:00 2001 From: Tadgh Date: Sat, 28 Jan 2023 09:28:15 -0800 Subject: [PATCH 3/9] Bump to 6.5 post-release-branch (#4472) * Create version enum and bump * Version bump * fix typo --- hapi-deployable-pom/pom.xml | 2 +- hapi-fhir-android/pom.xml | 2 +- hapi-fhir-base/pom.xml | 2 +- .../src/main/java/ca/uhn/fhir/util/VersionEnum.java | 4 +++- hapi-fhir-bom/pom.xml | 4 ++-- hapi-fhir-checkstyle/pom.xml | 2 +- hapi-fhir-cli/hapi-fhir-cli-api/pom.xml | 2 +- hapi-fhir-cli/hapi-fhir-cli-app/pom.xml | 2 +- hapi-fhir-cli/hapi-fhir-cli-jpaserver/pom.xml | 2 +- hapi-fhir-cli/pom.xml | 2 +- hapi-fhir-client-okhttp/pom.xml | 2 +- hapi-fhir-client/pom.xml | 2 +- hapi-fhir-converter/pom.xml | 2 +- hapi-fhir-dist/pom.xml | 2 +- hapi-fhir-docs/pom.xml | 2 +- .../resources/ca/uhn/hapi/fhir/changelog/6_6_0/upgrade.md | 0 .../resources/ca/uhn/hapi/fhir/changelog/6_6_0/version.yaml | 3 +++ hapi-fhir-jacoco/pom.xml | 2 +- hapi-fhir-jaxrsserver-base/pom.xml | 2 +- hapi-fhir-jpa/pom.xml | 2 +- hapi-fhir-jpaserver-base/pom.xml | 2 +- hapi-fhir-jpaserver-elastic-test-utilities/pom.xml | 2 +- hapi-fhir-jpaserver-ips/pom.xml | 2 +- hapi-fhir-jpaserver-mdm/pom.xml | 2 +- hapi-fhir-jpaserver-model/pom.xml | 2 +- hapi-fhir-jpaserver-searchparam/pom.xml | 2 +- hapi-fhir-jpaserver-subscription/pom.xml | 2 +- hapi-fhir-jpaserver-test-dstu2/pom.xml | 2 +- hapi-fhir-jpaserver-test-dstu3/pom.xml | 2 +- hapi-fhir-jpaserver-test-r4/pom.xml | 2 +- hapi-fhir-jpaserver-test-r4b/pom.xml | 2 +- hapi-fhir-jpaserver-test-r5/pom.xml | 2 +- hapi-fhir-jpaserver-test-utilities/pom.xml | 2 +- hapi-fhir-jpaserver-uhnfhirtest/pom.xml | 2 +- hapi-fhir-server-mdm/pom.xml | 2 +- hapi-fhir-server-openapi/pom.xml | 2 +- hapi-fhir-server/pom.xml | 2 +- hapi-fhir-serviceloaders/hapi-fhir-caching-api/pom.xml | 2 +- hapi-fhir-serviceloaders/hapi-fhir-caching-caffeine/pom.xml | 4 ++-- hapi-fhir-serviceloaders/hapi-fhir-caching-guava/pom.xml | 2 +- hapi-fhir-serviceloaders/hapi-fhir-caching-testing/pom.xml | 2 +- hapi-fhir-serviceloaders/pom.xml | 2 +- .../hapi-fhir-spring-boot-autoconfigure/pom.xml | 2 +- .../hapi-fhir-spring-boot-sample-client-apache/pom.xml | 2 +- .../hapi-fhir-spring-boot-sample-client-okhttp/pom.xml | 2 +- .../hapi-fhir-spring-boot-sample-server-jersey/pom.xml | 2 +- hapi-fhir-spring-boot/hapi-fhir-spring-boot-samples/pom.xml | 2 +- hapi-fhir-spring-boot/hapi-fhir-spring-boot-starter/pom.xml | 2 +- hapi-fhir-spring-boot/pom.xml | 2 +- hapi-fhir-sql-migrate/pom.xml | 2 +- hapi-fhir-storage-batch2-jobs/pom.xml | 2 +- hapi-fhir-storage-batch2/pom.xml | 2 +- hapi-fhir-storage-cr/pom.xml | 2 +- hapi-fhir-storage-mdm/pom.xml | 2 +- hapi-fhir-storage-test-utilities/pom.xml | 2 +- hapi-fhir-storage/pom.xml | 2 +- hapi-fhir-structures-dstu2.1/pom.xml | 2 +- hapi-fhir-structures-dstu2/pom.xml | 2 +- hapi-fhir-structures-dstu3/pom.xml | 2 +- hapi-fhir-structures-hl7org-dstu2/pom.xml | 2 +- hapi-fhir-structures-r4/pom.xml | 2 +- hapi-fhir-structures-r4b/pom.xml | 2 +- hapi-fhir-structures-r5/pom.xml | 2 +- hapi-fhir-test-utilities/pom.xml | 2 +- hapi-fhir-testpage-overlay/pom.xml | 2 +- hapi-fhir-validation-resources-dstu2.1/pom.xml | 2 +- hapi-fhir-validation-resources-dstu2/pom.xml | 2 +- hapi-fhir-validation-resources-dstu3/pom.xml | 2 +- hapi-fhir-validation-resources-r4/pom.xml | 2 +- hapi-fhir-validation-resources-r5/pom.xml | 2 +- hapi-fhir-validation/pom.xml | 2 +- hapi-tinder-plugin/pom.xml | 2 +- hapi-tinder-test/pom.xml | 2 +- pom.xml | 4 ++-- tests/hapi-fhir-base-test-jaxrsserver-kotlin/pom.xml | 2 +- tests/hapi-fhir-base-test-mindeps-client/pom.xml | 2 +- tests/hapi-fhir-base-test-mindeps-server/pom.xml | 2 +- 77 files changed, 83 insertions(+), 78 deletions(-) create mode 100644 hapi-fhir-docs/src/main/resources/ca/uhn/hapi/fhir/changelog/6_6_0/upgrade.md create mode 100644 hapi-fhir-docs/src/main/resources/ca/uhn/hapi/fhir/changelog/6_6_0/version.yaml diff --git a/hapi-deployable-pom/pom.xml b/hapi-deployable-pom/pom.xml index 8cb99220fea..2bb90c5f35b 100644 --- a/hapi-deployable-pom/pom.xml +++ b/hapi-deployable-pom/pom.xml @@ -4,7 +4,7 @@ ca.uhn.hapi.fhir hapi-fhir - 6.3.14-SNAPSHOT + 6.5.0-SNAPSHOT ../pom.xml diff --git a/hapi-fhir-android/pom.xml b/hapi-fhir-android/pom.xml index 6526e2d844f..232aaa38c8c 100644 --- a/hapi-fhir-android/pom.xml +++ b/hapi-fhir-android/pom.xml @@ -5,7 +5,7 @@ ca.uhn.hapi.fhir hapi-deployable-pom - 6.3.14-SNAPSHOT + 6.5.0-SNAPSHOT ../hapi-deployable-pom/pom.xml diff --git a/hapi-fhir-base/pom.xml b/hapi-fhir-base/pom.xml index 269d7037bce..8a5bc10ca9b 100644 --- a/hapi-fhir-base/pom.xml +++ b/hapi-fhir-base/pom.xml @@ -5,7 +5,7 @@ ca.uhn.hapi.fhir hapi-deployable-pom - 6.3.14-SNAPSHOT + 6.5.0-SNAPSHOT ../hapi-deployable-pom/pom.xml diff --git a/hapi-fhir-base/src/main/java/ca/uhn/fhir/util/VersionEnum.java b/hapi-fhir-base/src/main/java/ca/uhn/fhir/util/VersionEnum.java index 1133b25b887..f7913877e1e 100644 --- a/hapi-fhir-base/src/main/java/ca/uhn/fhir/util/VersionEnum.java +++ b/hapi-fhir-base/src/main/java/ca/uhn/fhir/util/VersionEnum.java @@ -113,7 +113,9 @@ public enum VersionEnum { V6_2_5, // Dev Build V6_3_0, - V6_4_0 + V6_4_0, + V6_5_0, + V6_6_0 ; public static VersionEnum latestVersion() { diff --git a/hapi-fhir-bom/pom.xml b/hapi-fhir-bom/pom.xml index 80f0465f630..1181e2b475b 100644 --- a/hapi-fhir-bom/pom.xml +++ b/hapi-fhir-bom/pom.xml @@ -4,14 +4,14 @@ 4.0.0 ca.uhn.hapi.fhir hapi-fhir-bom - 6.3.14-SNAPSHOT + 6.5.0-SNAPSHOT pom HAPI FHIR BOM ca.uhn.hapi.fhir hapi-deployable-pom - 6.3.14-SNAPSHOT + 6.5.0-SNAPSHOT ../hapi-deployable-pom/pom.xml diff --git a/hapi-fhir-checkstyle/pom.xml b/hapi-fhir-checkstyle/pom.xml index 12b5e688a7b..405d85e54ec 100644 --- a/hapi-fhir-checkstyle/pom.xml +++ b/hapi-fhir-checkstyle/pom.xml @@ -5,7 +5,7 @@ ca.uhn.hapi.fhir hapi-fhir - 6.3.14-SNAPSHOT + 6.5.0-SNAPSHOT ../pom.xml diff --git a/hapi-fhir-cli/hapi-fhir-cli-api/pom.xml b/hapi-fhir-cli/hapi-fhir-cli-api/pom.xml index 0df7eabbc6c..e33c3044bdd 100644 --- a/hapi-fhir-cli/hapi-fhir-cli-api/pom.xml +++ b/hapi-fhir-cli/hapi-fhir-cli-api/pom.xml @@ -4,7 +4,7 @@ ca.uhn.hapi.fhir hapi-deployable-pom - 6.3.14-SNAPSHOT + 6.5.0-SNAPSHOT ../../hapi-deployable-pom/pom.xml diff --git a/hapi-fhir-cli/hapi-fhir-cli-app/pom.xml b/hapi-fhir-cli/hapi-fhir-cli-app/pom.xml index 2fcf899b565..335b7741c35 100644 --- a/hapi-fhir-cli/hapi-fhir-cli-app/pom.xml +++ b/hapi-fhir-cli/hapi-fhir-cli-app/pom.xml @@ -6,7 +6,7 @@ ca.uhn.hapi.fhir hapi-fhir-cli - 6.3.14-SNAPSHOT + 6.5.0-SNAPSHOT ../pom.xml diff --git a/hapi-fhir-cli/hapi-fhir-cli-jpaserver/pom.xml b/hapi-fhir-cli/hapi-fhir-cli-jpaserver/pom.xml index 36923a20b4f..0f82ce2b222 100644 --- a/hapi-fhir-cli/hapi-fhir-cli-jpaserver/pom.xml +++ b/hapi-fhir-cli/hapi-fhir-cli-jpaserver/pom.xml @@ -6,7 +6,7 @@ ca.uhn.hapi.fhir hapi-deployable-pom - 6.3.14-SNAPSHOT + 6.5.0-SNAPSHOT ../../hapi-deployable-pom diff --git a/hapi-fhir-cli/pom.xml b/hapi-fhir-cli/pom.xml index 50f4c55da96..514ae1d3bb4 100644 --- a/hapi-fhir-cli/pom.xml +++ b/hapi-fhir-cli/pom.xml @@ -5,7 +5,7 @@ ca.uhn.hapi.fhir hapi-fhir - 6.3.14-SNAPSHOT + 6.5.0-SNAPSHOT ../pom.xml diff --git a/hapi-fhir-client-okhttp/pom.xml b/hapi-fhir-client-okhttp/pom.xml index 120dd6f69a0..27cfb6c19e2 100644 --- a/hapi-fhir-client-okhttp/pom.xml +++ b/hapi-fhir-client-okhttp/pom.xml @@ -4,7 +4,7 @@ ca.uhn.hapi.fhir hapi-deployable-pom - 6.3.14-SNAPSHOT + 6.5.0-SNAPSHOT ../hapi-deployable-pom/pom.xml diff --git a/hapi-fhir-client/pom.xml b/hapi-fhir-client/pom.xml index 65e6d79aa63..c4aa58471e2 100644 --- a/hapi-fhir-client/pom.xml +++ b/hapi-fhir-client/pom.xml @@ -4,7 +4,7 @@ ca.uhn.hapi.fhir hapi-deployable-pom - 6.3.14-SNAPSHOT + 6.5.0-SNAPSHOT ../hapi-deployable-pom/pom.xml diff --git a/hapi-fhir-converter/pom.xml b/hapi-fhir-converter/pom.xml index 7f2f73fc80e..9a78d790332 100644 --- a/hapi-fhir-converter/pom.xml +++ b/hapi-fhir-converter/pom.xml @@ -5,7 +5,7 @@ ca.uhn.hapi.fhir hapi-deployable-pom - 6.3.14-SNAPSHOT + 6.5.0-SNAPSHOT ../hapi-deployable-pom/pom.xml diff --git a/hapi-fhir-dist/pom.xml b/hapi-fhir-dist/pom.xml index f8f10fafeb0..0e3a5655c5a 100644 --- a/hapi-fhir-dist/pom.xml +++ b/hapi-fhir-dist/pom.xml @@ -5,7 +5,7 @@ ca.uhn.hapi.fhir hapi-fhir - 6.3.14-SNAPSHOT + 6.5.0-SNAPSHOT ../pom.xml diff --git a/hapi-fhir-docs/pom.xml b/hapi-fhir-docs/pom.xml index f90af5cb5fc..b649090ddc2 100644 --- a/hapi-fhir-docs/pom.xml +++ b/hapi-fhir-docs/pom.xml @@ -5,7 +5,7 @@ ca.uhn.hapi.fhir hapi-deployable-pom - 6.3.14-SNAPSHOT + 6.5.0-SNAPSHOT ../hapi-deployable-pom/pom.xml diff --git a/hapi-fhir-docs/src/main/resources/ca/uhn/hapi/fhir/changelog/6_6_0/upgrade.md b/hapi-fhir-docs/src/main/resources/ca/uhn/hapi/fhir/changelog/6_6_0/upgrade.md new file mode 100644 index 00000000000..e69de29bb2d diff --git a/hapi-fhir-docs/src/main/resources/ca/uhn/hapi/fhir/changelog/6_6_0/version.yaml b/hapi-fhir-docs/src/main/resources/ca/uhn/hapi/fhir/changelog/6_6_0/version.yaml new file mode 100644 index 00000000000..2de22c443a8 --- /dev/null +++ b/hapi-fhir-docs/src/main/resources/ca/uhn/hapi/fhir/changelog/6_6_0/version.yaml @@ -0,0 +1,3 @@ +--- +release-date: "2023-05-18" +codename: "TBD" diff --git a/hapi-fhir-jacoco/pom.xml b/hapi-fhir-jacoco/pom.xml index 9494c835c31..86f9ee779f9 100644 --- a/hapi-fhir-jacoco/pom.xml +++ b/hapi-fhir-jacoco/pom.xml @@ -11,7 +11,7 @@ ca.uhn.hapi.fhir hapi-deployable-pom - 6.3.14-SNAPSHOT + 6.5.0-SNAPSHOT ../hapi-deployable-pom/pom.xml diff --git a/hapi-fhir-jaxrsserver-base/pom.xml b/hapi-fhir-jaxrsserver-base/pom.xml index 8ed093981c4..0b0b0c3e7b7 100644 --- a/hapi-fhir-jaxrsserver-base/pom.xml +++ b/hapi-fhir-jaxrsserver-base/pom.xml @@ -4,7 +4,7 @@ ca.uhn.hapi.fhir hapi-deployable-pom - 6.3.14-SNAPSHOT + 6.5.0-SNAPSHOT ../hapi-deployable-pom/pom.xml diff --git a/hapi-fhir-jpa/pom.xml b/hapi-fhir-jpa/pom.xml index d5630cd4363..a737d783636 100644 --- a/hapi-fhir-jpa/pom.xml +++ b/hapi-fhir-jpa/pom.xml @@ -5,7 +5,7 @@ ca.uhn.hapi.fhir hapi-deployable-pom - 6.3.14-SNAPSHOT + 6.5.0-SNAPSHOT ../hapi-deployable-pom/pom.xml 4.0.0 diff --git a/hapi-fhir-jpaserver-base/pom.xml b/hapi-fhir-jpaserver-base/pom.xml index 44c5e67b405..6092854b267 100644 --- a/hapi-fhir-jpaserver-base/pom.xml +++ b/hapi-fhir-jpaserver-base/pom.xml @@ -5,7 +5,7 @@ ca.uhn.hapi.fhir hapi-deployable-pom - 6.3.14-SNAPSHOT + 6.5.0-SNAPSHOT ../hapi-deployable-pom/pom.xml diff --git a/hapi-fhir-jpaserver-elastic-test-utilities/pom.xml b/hapi-fhir-jpaserver-elastic-test-utilities/pom.xml index 6c6b3e6c5f6..b57faeedb92 100644 --- a/hapi-fhir-jpaserver-elastic-test-utilities/pom.xml +++ b/hapi-fhir-jpaserver-elastic-test-utilities/pom.xml @@ -6,7 +6,7 @@ ca.uhn.hapi.fhir hapi-deployable-pom - 6.3.14-SNAPSHOT + 6.5.0-SNAPSHOT ../hapi-deployable-pom/pom.xml diff --git a/hapi-fhir-jpaserver-ips/pom.xml b/hapi-fhir-jpaserver-ips/pom.xml index e52aea6b752..705cf1ee742 100644 --- a/hapi-fhir-jpaserver-ips/pom.xml +++ b/hapi-fhir-jpaserver-ips/pom.xml @@ -3,7 +3,7 @@ ca.uhn.hapi.fhir hapi-deployable-pom - 6.3.14-SNAPSHOT + 6.5.0-SNAPSHOT ../hapi-deployable-pom/pom.xml diff --git a/hapi-fhir-jpaserver-mdm/pom.xml b/hapi-fhir-jpaserver-mdm/pom.xml index 15aa9542fa4..252539e79cc 100644 --- a/hapi-fhir-jpaserver-mdm/pom.xml +++ b/hapi-fhir-jpaserver-mdm/pom.xml @@ -6,7 +6,7 @@ ca.uhn.hapi.fhir hapi-deployable-pom - 6.3.14-SNAPSHOT + 6.5.0-SNAPSHOT ../hapi-deployable-pom/pom.xml diff --git a/hapi-fhir-jpaserver-model/pom.xml b/hapi-fhir-jpaserver-model/pom.xml index a105674e4fa..06b7e2cf3d7 100644 --- a/hapi-fhir-jpaserver-model/pom.xml +++ b/hapi-fhir-jpaserver-model/pom.xml @@ -5,7 +5,7 @@ ca.uhn.hapi.fhir hapi-deployable-pom - 6.3.14-SNAPSHOT + 6.5.0-SNAPSHOT ../hapi-deployable-pom/pom.xml diff --git a/hapi-fhir-jpaserver-searchparam/pom.xml b/hapi-fhir-jpaserver-searchparam/pom.xml index 119880cd395..c3825b656d3 100755 --- a/hapi-fhir-jpaserver-searchparam/pom.xml +++ b/hapi-fhir-jpaserver-searchparam/pom.xml @@ -5,7 +5,7 @@ ca.uhn.hapi.fhir hapi-deployable-pom - 6.3.14-SNAPSHOT + 6.5.0-SNAPSHOT ../hapi-deployable-pom/pom.xml diff --git a/hapi-fhir-jpaserver-subscription/pom.xml b/hapi-fhir-jpaserver-subscription/pom.xml index 8dd6082afeb..39e1b4a3c67 100644 --- a/hapi-fhir-jpaserver-subscription/pom.xml +++ b/hapi-fhir-jpaserver-subscription/pom.xml @@ -5,7 +5,7 @@ ca.uhn.hapi.fhir hapi-deployable-pom - 6.3.14-SNAPSHOT + 6.5.0-SNAPSHOT ../hapi-deployable-pom/pom.xml diff --git a/hapi-fhir-jpaserver-test-dstu2/pom.xml b/hapi-fhir-jpaserver-test-dstu2/pom.xml index 1bdf83b72ee..0be6f861084 100644 --- a/hapi-fhir-jpaserver-test-dstu2/pom.xml +++ b/hapi-fhir-jpaserver-test-dstu2/pom.xml @@ -6,7 +6,7 @@ ca.uhn.hapi.fhir hapi-deployable-pom - 6.3.14-SNAPSHOT + 6.5.0-SNAPSHOT ../hapi-deployable-pom/pom.xml diff --git a/hapi-fhir-jpaserver-test-dstu3/pom.xml b/hapi-fhir-jpaserver-test-dstu3/pom.xml index f5797e922c1..0c940988c9f 100644 --- a/hapi-fhir-jpaserver-test-dstu3/pom.xml +++ b/hapi-fhir-jpaserver-test-dstu3/pom.xml @@ -6,7 +6,7 @@ ca.uhn.hapi.fhir hapi-deployable-pom - 6.3.14-SNAPSHOT + 6.5.0-SNAPSHOT ../hapi-deployable-pom/pom.xml diff --git a/hapi-fhir-jpaserver-test-r4/pom.xml b/hapi-fhir-jpaserver-test-r4/pom.xml index 28e74fa348d..4cb44fd2115 100644 --- a/hapi-fhir-jpaserver-test-r4/pom.xml +++ b/hapi-fhir-jpaserver-test-r4/pom.xml @@ -6,7 +6,7 @@ ca.uhn.hapi.fhir hapi-deployable-pom - 6.3.14-SNAPSHOT + 6.5.0-SNAPSHOT ../hapi-deployable-pom/pom.xml diff --git a/hapi-fhir-jpaserver-test-r4b/pom.xml b/hapi-fhir-jpaserver-test-r4b/pom.xml index c11ae5a2df8..309fc0bfe0d 100644 --- a/hapi-fhir-jpaserver-test-r4b/pom.xml +++ b/hapi-fhir-jpaserver-test-r4b/pom.xml @@ -6,7 +6,7 @@ ca.uhn.hapi.fhir hapi-deployable-pom - 6.3.14-SNAPSHOT + 6.5.0-SNAPSHOT ../hapi-deployable-pom/pom.xml diff --git a/hapi-fhir-jpaserver-test-r5/pom.xml b/hapi-fhir-jpaserver-test-r5/pom.xml index 7060c408d81..b9cb45f6d29 100644 --- a/hapi-fhir-jpaserver-test-r5/pom.xml +++ b/hapi-fhir-jpaserver-test-r5/pom.xml @@ -6,7 +6,7 @@ ca.uhn.hapi.fhir hapi-deployable-pom - 6.3.14-SNAPSHOT + 6.5.0-SNAPSHOT ../hapi-deployable-pom/pom.xml diff --git a/hapi-fhir-jpaserver-test-utilities/pom.xml b/hapi-fhir-jpaserver-test-utilities/pom.xml index fc01acda8a3..d1314d7195f 100644 --- a/hapi-fhir-jpaserver-test-utilities/pom.xml +++ b/hapi-fhir-jpaserver-test-utilities/pom.xml @@ -6,7 +6,7 @@ ca.uhn.hapi.fhir hapi-deployable-pom - 6.3.14-SNAPSHOT + 6.5.0-SNAPSHOT ../hapi-deployable-pom/pom.xml diff --git a/hapi-fhir-jpaserver-uhnfhirtest/pom.xml b/hapi-fhir-jpaserver-uhnfhirtest/pom.xml index 35754d1c594..f6180eaca46 100644 --- a/hapi-fhir-jpaserver-uhnfhirtest/pom.xml +++ b/hapi-fhir-jpaserver-uhnfhirtest/pom.xml @@ -5,7 +5,7 @@ ca.uhn.hapi.fhir hapi-fhir - 6.3.14-SNAPSHOT + 6.5.0-SNAPSHOT ../pom.xml diff --git a/hapi-fhir-server-mdm/pom.xml b/hapi-fhir-server-mdm/pom.xml index 244a4e150be..34e52715915 100644 --- a/hapi-fhir-server-mdm/pom.xml +++ b/hapi-fhir-server-mdm/pom.xml @@ -7,7 +7,7 @@ ca.uhn.hapi.fhir hapi-deployable-pom - 6.3.14-SNAPSHOT + 6.5.0-SNAPSHOT ../hapi-deployable-pom/pom.xml diff --git a/hapi-fhir-server-openapi/pom.xml b/hapi-fhir-server-openapi/pom.xml index 09d5cfc1f09..afc55be6399 100644 --- a/hapi-fhir-server-openapi/pom.xml +++ b/hapi-fhir-server-openapi/pom.xml @@ -5,7 +5,7 @@ ca.uhn.hapi.fhir hapi-deployable-pom - 6.3.14-SNAPSHOT + 6.5.0-SNAPSHOT ../hapi-deployable-pom/pom.xml diff --git a/hapi-fhir-server/pom.xml b/hapi-fhir-server/pom.xml index d4b4abe54dd..d4f12e754ee 100644 --- a/hapi-fhir-server/pom.xml +++ b/hapi-fhir-server/pom.xml @@ -5,7 +5,7 @@ ca.uhn.hapi.fhir hapi-deployable-pom - 6.3.14-SNAPSHOT + 6.5.0-SNAPSHOT ../hapi-deployable-pom/pom.xml diff --git a/hapi-fhir-serviceloaders/hapi-fhir-caching-api/pom.xml b/hapi-fhir-serviceloaders/hapi-fhir-caching-api/pom.xml index 3a198fe53b6..b182513178a 100644 --- a/hapi-fhir-serviceloaders/hapi-fhir-caching-api/pom.xml +++ b/hapi-fhir-serviceloaders/hapi-fhir-caching-api/pom.xml @@ -7,7 +7,7 @@ hapi-fhir-serviceloaders ca.uhn.hapi.fhir - 6.3.14-SNAPSHOT + 6.5.0-SNAPSHOT ../pom.xml diff --git a/hapi-fhir-serviceloaders/hapi-fhir-caching-caffeine/pom.xml b/hapi-fhir-serviceloaders/hapi-fhir-caching-caffeine/pom.xml index 3db8187c54d..84d52892290 100644 --- a/hapi-fhir-serviceloaders/hapi-fhir-caching-caffeine/pom.xml +++ b/hapi-fhir-serviceloaders/hapi-fhir-caching-caffeine/pom.xml @@ -7,7 +7,7 @@ hapi-fhir-serviceloaders ca.uhn.hapi.fhir - 6.3.14-SNAPSHOT + 6.5.0-SNAPSHOT ../pom.xml @@ -20,7 +20,7 @@ ca.uhn.hapi.fhir hapi-fhir-caching-api - 6.3.14-SNAPSHOT + 6.5.0-SNAPSHOT com.github.ben-manes.caffeine diff --git a/hapi-fhir-serviceloaders/hapi-fhir-caching-guava/pom.xml b/hapi-fhir-serviceloaders/hapi-fhir-caching-guava/pom.xml index e58f3afc9ff..3e2e09f2cd4 100644 --- a/hapi-fhir-serviceloaders/hapi-fhir-caching-guava/pom.xml +++ b/hapi-fhir-serviceloaders/hapi-fhir-caching-guava/pom.xml @@ -7,7 +7,7 @@ hapi-fhir-serviceloaders ca.uhn.hapi.fhir - 6.3.14-SNAPSHOT + 6.5.0-SNAPSHOT ../pom.xml diff --git a/hapi-fhir-serviceloaders/hapi-fhir-caching-testing/pom.xml b/hapi-fhir-serviceloaders/hapi-fhir-caching-testing/pom.xml index 8a320dedd4b..589d0b19818 100644 --- a/hapi-fhir-serviceloaders/hapi-fhir-caching-testing/pom.xml +++ b/hapi-fhir-serviceloaders/hapi-fhir-caching-testing/pom.xml @@ -7,7 +7,7 @@ hapi-fhir ca.uhn.hapi.fhir - 6.3.14-SNAPSHOT + 6.5.0-SNAPSHOT ../../pom.xml diff --git a/hapi-fhir-serviceloaders/pom.xml b/hapi-fhir-serviceloaders/pom.xml index bc7ea7deba4..5581ed3b03d 100644 --- a/hapi-fhir-serviceloaders/pom.xml +++ b/hapi-fhir-serviceloaders/pom.xml @@ -5,7 +5,7 @@ hapi-fhir ca.uhn.hapi.fhir - 6.3.14-SNAPSHOT + 6.5.0-SNAPSHOT ../pom.xml diff --git a/hapi-fhir-spring-boot/hapi-fhir-spring-boot-autoconfigure/pom.xml b/hapi-fhir-spring-boot/hapi-fhir-spring-boot-autoconfigure/pom.xml index 8b6fdd97fec..332e9c99314 100644 --- a/hapi-fhir-spring-boot/hapi-fhir-spring-boot-autoconfigure/pom.xml +++ b/hapi-fhir-spring-boot/hapi-fhir-spring-boot-autoconfigure/pom.xml @@ -5,7 +5,7 @@ ca.uhn.hapi.fhir hapi-deployable-pom - 6.3.14-SNAPSHOT + 6.5.0-SNAPSHOT ../../hapi-deployable-pom/pom.xml diff --git a/hapi-fhir-spring-boot/hapi-fhir-spring-boot-samples/hapi-fhir-spring-boot-sample-client-apache/pom.xml b/hapi-fhir-spring-boot/hapi-fhir-spring-boot-samples/hapi-fhir-spring-boot-sample-client-apache/pom.xml index ea7b07a4ccc..3b4a537586a 100644 --- a/hapi-fhir-spring-boot/hapi-fhir-spring-boot-samples/hapi-fhir-spring-boot-sample-client-apache/pom.xml +++ b/hapi-fhir-spring-boot/hapi-fhir-spring-boot-samples/hapi-fhir-spring-boot-sample-client-apache/pom.xml @@ -5,7 +5,7 @@ ca.uhn.hapi.fhir hapi-fhir-spring-boot-samples - 6.3.14-SNAPSHOT + 6.5.0-SNAPSHOT hapi-fhir-spring-boot-sample-client-apache diff --git a/hapi-fhir-spring-boot/hapi-fhir-spring-boot-samples/hapi-fhir-spring-boot-sample-client-okhttp/pom.xml b/hapi-fhir-spring-boot/hapi-fhir-spring-boot-samples/hapi-fhir-spring-boot-sample-client-okhttp/pom.xml index 4f6393f7c0b..3fa44b39612 100644 --- a/hapi-fhir-spring-boot/hapi-fhir-spring-boot-samples/hapi-fhir-spring-boot-sample-client-okhttp/pom.xml +++ b/hapi-fhir-spring-boot/hapi-fhir-spring-boot-samples/hapi-fhir-spring-boot-sample-client-okhttp/pom.xml @@ -5,7 +5,7 @@ ca.uhn.hapi.fhir hapi-fhir-spring-boot-samples - 6.3.14-SNAPSHOT + 6.5.0-SNAPSHOT hapi-fhir-spring-boot-sample-client-okhttp diff --git a/hapi-fhir-spring-boot/hapi-fhir-spring-boot-samples/hapi-fhir-spring-boot-sample-server-jersey/pom.xml b/hapi-fhir-spring-boot/hapi-fhir-spring-boot-samples/hapi-fhir-spring-boot-sample-server-jersey/pom.xml index 3ec1440cb18..8ea45a9e9e5 100644 --- a/hapi-fhir-spring-boot/hapi-fhir-spring-boot-samples/hapi-fhir-spring-boot-sample-server-jersey/pom.xml +++ b/hapi-fhir-spring-boot/hapi-fhir-spring-boot-samples/hapi-fhir-spring-boot-sample-server-jersey/pom.xml @@ -5,7 +5,7 @@ ca.uhn.hapi.fhir hapi-fhir-spring-boot-samples - 6.3.14-SNAPSHOT + 6.5.0-SNAPSHOT hapi-fhir-spring-boot-sample-server-jersey diff --git a/hapi-fhir-spring-boot/hapi-fhir-spring-boot-samples/pom.xml b/hapi-fhir-spring-boot/hapi-fhir-spring-boot-samples/pom.xml index 92e14112893..bfd0ff929f5 100644 --- a/hapi-fhir-spring-boot/hapi-fhir-spring-boot-samples/pom.xml +++ b/hapi-fhir-spring-boot/hapi-fhir-spring-boot-samples/pom.xml @@ -5,7 +5,7 @@ ca.uhn.hapi.fhir hapi-fhir-spring-boot - 6.3.14-SNAPSHOT + 6.5.0-SNAPSHOT hapi-fhir-spring-boot-samples diff --git a/hapi-fhir-spring-boot/hapi-fhir-spring-boot-starter/pom.xml b/hapi-fhir-spring-boot/hapi-fhir-spring-boot-starter/pom.xml index d3a530ce6a0..d17f78539b4 100644 --- a/hapi-fhir-spring-boot/hapi-fhir-spring-boot-starter/pom.xml +++ b/hapi-fhir-spring-boot/hapi-fhir-spring-boot-starter/pom.xml @@ -5,7 +5,7 @@ ca.uhn.hapi.fhir hapi-deployable-pom - 6.3.14-SNAPSHOT + 6.5.0-SNAPSHOT ../../hapi-deployable-pom/pom.xml diff --git a/hapi-fhir-spring-boot/pom.xml b/hapi-fhir-spring-boot/pom.xml index aafd16791fe..8b7da530410 100644 --- a/hapi-fhir-spring-boot/pom.xml +++ b/hapi-fhir-spring-boot/pom.xml @@ -5,7 +5,7 @@ ca.uhn.hapi.fhir hapi-fhir - 6.3.14-SNAPSHOT + 6.5.0-SNAPSHOT ../pom.xml diff --git a/hapi-fhir-sql-migrate/pom.xml b/hapi-fhir-sql-migrate/pom.xml index 7f465bd3e06..2294911d5c6 100644 --- a/hapi-fhir-sql-migrate/pom.xml +++ b/hapi-fhir-sql-migrate/pom.xml @@ -5,7 +5,7 @@ ca.uhn.hapi.fhir hapi-deployable-pom - 6.3.14-SNAPSHOT + 6.5.0-SNAPSHOT ../hapi-deployable-pom/pom.xml diff --git a/hapi-fhir-storage-batch2-jobs/pom.xml b/hapi-fhir-storage-batch2-jobs/pom.xml index e2e613dfadf..7d2da2c06d0 100644 --- a/hapi-fhir-storage-batch2-jobs/pom.xml +++ b/hapi-fhir-storage-batch2-jobs/pom.xml @@ -5,7 +5,7 @@ ca.uhn.hapi.fhir hapi-deployable-pom - 6.3.14-SNAPSHOT + 6.5.0-SNAPSHOT ../hapi-deployable-pom/pom.xml 4.0.0 diff --git a/hapi-fhir-storage-batch2/pom.xml b/hapi-fhir-storage-batch2/pom.xml index dd334e97348..47e6c81d6e0 100644 --- a/hapi-fhir-storage-batch2/pom.xml +++ b/hapi-fhir-storage-batch2/pom.xml @@ -6,7 +6,7 @@ ca.uhn.hapi.fhir hapi-deployable-pom - 6.3.14-SNAPSHOT + 6.5.0-SNAPSHOT ../hapi-deployable-pom/pom.xml diff --git a/hapi-fhir-storage-cr/pom.xml b/hapi-fhir-storage-cr/pom.xml index d526868807a..a7c82542be7 100644 --- a/hapi-fhir-storage-cr/pom.xml +++ b/hapi-fhir-storage-cr/pom.xml @@ -7,7 +7,7 @@ ca.uhn.hapi.fhir hapi-deployable-pom - 6.3.14-SNAPSHOT + 6.5.0-SNAPSHOT ../hapi-deployable-pom/pom.xml diff --git a/hapi-fhir-storage-mdm/pom.xml b/hapi-fhir-storage-mdm/pom.xml index a6398f0e0bf..acf055b627e 100644 --- a/hapi-fhir-storage-mdm/pom.xml +++ b/hapi-fhir-storage-mdm/pom.xml @@ -5,7 +5,7 @@ ca.uhn.hapi.fhir hapi-deployable-pom - 6.3.14-SNAPSHOT + 6.5.0-SNAPSHOT ../hapi-deployable-pom/pom.xml 4.0.0 diff --git a/hapi-fhir-storage-test-utilities/pom.xml b/hapi-fhir-storage-test-utilities/pom.xml index 0418ffd4544..59972c1685f 100644 --- a/hapi-fhir-storage-test-utilities/pom.xml +++ b/hapi-fhir-storage-test-utilities/pom.xml @@ -5,7 +5,7 @@ ca.uhn.hapi.fhir hapi-deployable-pom - 6.3.14-SNAPSHOT + 6.5.0-SNAPSHOT ../hapi-deployable-pom/pom.xml 4.0.0 diff --git a/hapi-fhir-storage/pom.xml b/hapi-fhir-storage/pom.xml index eb487e974c3..b72e1f0a85a 100644 --- a/hapi-fhir-storage/pom.xml +++ b/hapi-fhir-storage/pom.xml @@ -5,7 +5,7 @@ ca.uhn.hapi.fhir hapi-deployable-pom - 6.3.14-SNAPSHOT + 6.5.0-SNAPSHOT ../hapi-deployable-pom/pom.xml diff --git a/hapi-fhir-structures-dstu2.1/pom.xml b/hapi-fhir-structures-dstu2.1/pom.xml index 104266a8abe..272dbdcfd74 100644 --- a/hapi-fhir-structures-dstu2.1/pom.xml +++ b/hapi-fhir-structures-dstu2.1/pom.xml @@ -5,7 +5,7 @@ ca.uhn.hapi.fhir hapi-deployable-pom - 6.3.14-SNAPSHOT + 6.5.0-SNAPSHOT ../hapi-deployable-pom/pom.xml diff --git a/hapi-fhir-structures-dstu2/pom.xml b/hapi-fhir-structures-dstu2/pom.xml index c80e11b4ab5..f8439d45995 100644 --- a/hapi-fhir-structures-dstu2/pom.xml +++ b/hapi-fhir-structures-dstu2/pom.xml @@ -4,7 +4,7 @@ ca.uhn.hapi.fhir hapi-deployable-pom - 6.3.14-SNAPSHOT + 6.5.0-SNAPSHOT ../hapi-deployable-pom/pom.xml diff --git a/hapi-fhir-structures-dstu3/pom.xml b/hapi-fhir-structures-dstu3/pom.xml index 1a28e61dcfd..a66018c6136 100644 --- a/hapi-fhir-structures-dstu3/pom.xml +++ b/hapi-fhir-structures-dstu3/pom.xml @@ -5,7 +5,7 @@ ca.uhn.hapi.fhir hapi-deployable-pom - 6.3.14-SNAPSHOT + 6.5.0-SNAPSHOT ../hapi-deployable-pom/pom.xml diff --git a/hapi-fhir-structures-hl7org-dstu2/pom.xml b/hapi-fhir-structures-hl7org-dstu2/pom.xml index c486671fc7c..bc25b48bd32 100644 --- a/hapi-fhir-structures-hl7org-dstu2/pom.xml +++ b/hapi-fhir-structures-hl7org-dstu2/pom.xml @@ -5,7 +5,7 @@ ca.uhn.hapi.fhir hapi-deployable-pom - 6.3.14-SNAPSHOT + 6.5.0-SNAPSHOT ../hapi-deployable-pom/pom.xml diff --git a/hapi-fhir-structures-r4/pom.xml b/hapi-fhir-structures-r4/pom.xml index 01f7b6163e8..94509717a42 100644 --- a/hapi-fhir-structures-r4/pom.xml +++ b/hapi-fhir-structures-r4/pom.xml @@ -5,7 +5,7 @@ ca.uhn.hapi.fhir hapi-deployable-pom - 6.3.14-SNAPSHOT + 6.5.0-SNAPSHOT ../hapi-deployable-pom/pom.xml diff --git a/hapi-fhir-structures-r4b/pom.xml b/hapi-fhir-structures-r4b/pom.xml index 477572bda4a..74be257e156 100644 --- a/hapi-fhir-structures-r4b/pom.xml +++ b/hapi-fhir-structures-r4b/pom.xml @@ -5,7 +5,7 @@ ca.uhn.hapi.fhir hapi-deployable-pom - 6.3.14-SNAPSHOT + 6.5.0-SNAPSHOT ../hapi-deployable-pom/pom.xml diff --git a/hapi-fhir-structures-r5/pom.xml b/hapi-fhir-structures-r5/pom.xml index b88b92ffb83..65fe915fde1 100644 --- a/hapi-fhir-structures-r5/pom.xml +++ b/hapi-fhir-structures-r5/pom.xml @@ -5,7 +5,7 @@ ca.uhn.hapi.fhir hapi-deployable-pom - 6.3.14-SNAPSHOT + 6.5.0-SNAPSHOT ../hapi-deployable-pom/pom.xml diff --git a/hapi-fhir-test-utilities/pom.xml b/hapi-fhir-test-utilities/pom.xml index de8a86a686e..739892aa343 100644 --- a/hapi-fhir-test-utilities/pom.xml +++ b/hapi-fhir-test-utilities/pom.xml @@ -5,7 +5,7 @@ ca.uhn.hapi.fhir hapi-deployable-pom - 6.3.14-SNAPSHOT + 6.5.0-SNAPSHOT ../hapi-deployable-pom/pom.xml diff --git a/hapi-fhir-testpage-overlay/pom.xml b/hapi-fhir-testpage-overlay/pom.xml index 92298aefe31..92e68cf0795 100644 --- a/hapi-fhir-testpage-overlay/pom.xml +++ b/hapi-fhir-testpage-overlay/pom.xml @@ -5,7 +5,7 @@ ca.uhn.hapi.fhir hapi-fhir - 6.3.14-SNAPSHOT + 6.5.0-SNAPSHOT ../pom.xml diff --git a/hapi-fhir-validation-resources-dstu2.1/pom.xml b/hapi-fhir-validation-resources-dstu2.1/pom.xml index 149494e2c09..4b971f6c5ad 100644 --- a/hapi-fhir-validation-resources-dstu2.1/pom.xml +++ b/hapi-fhir-validation-resources-dstu2.1/pom.xml @@ -4,7 +4,7 @@ ca.uhn.hapi.fhir hapi-deployable-pom - 6.3.14-SNAPSHOT + 6.5.0-SNAPSHOT ../hapi-deployable-pom/pom.xml diff --git a/hapi-fhir-validation-resources-dstu2/pom.xml b/hapi-fhir-validation-resources-dstu2/pom.xml index 9317ff0611d..5fac1e3d10a 100644 --- a/hapi-fhir-validation-resources-dstu2/pom.xml +++ b/hapi-fhir-validation-resources-dstu2/pom.xml @@ -4,7 +4,7 @@ ca.uhn.hapi.fhir hapi-deployable-pom - 6.3.14-SNAPSHOT + 6.5.0-SNAPSHOT ../hapi-deployable-pom/pom.xml diff --git a/hapi-fhir-validation-resources-dstu3/pom.xml b/hapi-fhir-validation-resources-dstu3/pom.xml index 3ae7b8be7c5..7aaa6e4aa3f 100644 --- a/hapi-fhir-validation-resources-dstu3/pom.xml +++ b/hapi-fhir-validation-resources-dstu3/pom.xml @@ -4,7 +4,7 @@ ca.uhn.hapi.fhir hapi-deployable-pom - 6.3.14-SNAPSHOT + 6.5.0-SNAPSHOT ../hapi-deployable-pom/pom.xml diff --git a/hapi-fhir-validation-resources-r4/pom.xml b/hapi-fhir-validation-resources-r4/pom.xml index e372901ae19..7000646f160 100644 --- a/hapi-fhir-validation-resources-r4/pom.xml +++ b/hapi-fhir-validation-resources-r4/pom.xml @@ -4,7 +4,7 @@ ca.uhn.hapi.fhir hapi-deployable-pom - 6.3.14-SNAPSHOT + 6.5.0-SNAPSHOT ../hapi-deployable-pom/pom.xml diff --git a/hapi-fhir-validation-resources-r5/pom.xml b/hapi-fhir-validation-resources-r5/pom.xml index 5fa0d7acaf3..96cdc9f8afa 100644 --- a/hapi-fhir-validation-resources-r5/pom.xml +++ b/hapi-fhir-validation-resources-r5/pom.xml @@ -4,7 +4,7 @@ ca.uhn.hapi.fhir hapi-deployable-pom - 6.3.14-SNAPSHOT + 6.5.0-SNAPSHOT ../hapi-deployable-pom/pom.xml diff --git a/hapi-fhir-validation/pom.xml b/hapi-fhir-validation/pom.xml index 0012fe578e5..a8079c72ef9 100644 --- a/hapi-fhir-validation/pom.xml +++ b/hapi-fhir-validation/pom.xml @@ -5,7 +5,7 @@ ca.uhn.hapi.fhir hapi-deployable-pom - 6.3.14-SNAPSHOT + 6.5.0-SNAPSHOT ../hapi-deployable-pom/pom.xml diff --git a/hapi-tinder-plugin/pom.xml b/hapi-tinder-plugin/pom.xml index 259e7c43bbd..4f824bb81c8 100644 --- a/hapi-tinder-plugin/pom.xml +++ b/hapi-tinder-plugin/pom.xml @@ -5,7 +5,7 @@ ca.uhn.hapi.fhir hapi-fhir - 6.3.14-SNAPSHOT + 6.5.0-SNAPSHOT ../pom.xml diff --git a/hapi-tinder-test/pom.xml b/hapi-tinder-test/pom.xml index bd99b33ed39..675bc8c3168 100644 --- a/hapi-tinder-test/pom.xml +++ b/hapi-tinder-test/pom.xml @@ -4,7 +4,7 @@ ca.uhn.hapi.fhir hapi-fhir - 6.3.14-SNAPSHOT + 6.5.0-SNAPSHOT ../pom.xml diff --git a/pom.xml b/pom.xml index b178c74e73c..000451e375f 100644 --- a/pom.xml +++ b/pom.xml @@ -6,7 +6,7 @@ ca.uhn.hapi.fhir hapi-fhir pom - 6.3.14-SNAPSHOT + 6.5.0-SNAPSHOT HAPI-FHIR An open-source implementation of the FHIR specification in Java. https://hapifhir.io @@ -2137,7 +2137,7 @@ ca.uhn.hapi.fhir hapi-fhir-checkstyle - 6.3.14-SNAPSHOT + 6.5.0-SNAPSHOT diff --git a/tests/hapi-fhir-base-test-jaxrsserver-kotlin/pom.xml b/tests/hapi-fhir-base-test-jaxrsserver-kotlin/pom.xml index 9c449d93b38..aabb0d585f0 100644 --- a/tests/hapi-fhir-base-test-jaxrsserver-kotlin/pom.xml +++ b/tests/hapi-fhir-base-test-jaxrsserver-kotlin/pom.xml @@ -6,7 +6,7 @@ ca.uhn.hapi.fhir hapi-fhir - 6.3.14-SNAPSHOT + 6.5.0-SNAPSHOT ../../pom.xml diff --git a/tests/hapi-fhir-base-test-mindeps-client/pom.xml b/tests/hapi-fhir-base-test-mindeps-client/pom.xml index 0dd0d834c18..0ccbc522c0a 100644 --- a/tests/hapi-fhir-base-test-mindeps-client/pom.xml +++ b/tests/hapi-fhir-base-test-mindeps-client/pom.xml @@ -4,7 +4,7 @@ ca.uhn.hapi.fhir hapi-fhir - 6.3.14-SNAPSHOT + 6.5.0-SNAPSHOT ../../pom.xml diff --git a/tests/hapi-fhir-base-test-mindeps-server/pom.xml b/tests/hapi-fhir-base-test-mindeps-server/pom.xml index 74ea4e9adb0..4daf5970442 100644 --- a/tests/hapi-fhir-base-test-mindeps-server/pom.xml +++ b/tests/hapi-fhir-base-test-mindeps-server/pom.xml @@ -5,7 +5,7 @@ ca.uhn.hapi.fhir hapi-fhir - 6.3.14-SNAPSHOT + 6.5.0-SNAPSHOT ../../pom.xml From eaa1e6265576d4b9a696bf998551ff0a71b4c342 Mon Sep 17 00:00:00 2001 From: JorisHeadease Date: Mon, 30 Jan 2023 13:24:40 +0100 Subject: [PATCH 4/9] Added information on how referential integrity works in HAPI. Only indexed fields are validated. Devs might expect foreign-key constraints when enabling this option. (#4479) Co-authored-by: Joris Scharp --- .../fhir/docs/server_jpa/configuration.md | 31 +++++++++++++++++++ 1 file changed, 31 insertions(+) diff --git a/hapi-fhir-docs/src/main/resources/ca/uhn/hapi/fhir/docs/server_jpa/configuration.md b/hapi-fhir-docs/src/main/resources/ca/uhn/hapi/fhir/docs/server_jpa/configuration.md index d927d12d64a..1a171488773 100644 --- a/hapi-fhir-docs/src/main/resources/ca/uhn/hapi/fhir/docs/server_jpa/configuration.md +++ b/hapi-fhir-docs/src/main/resources/ca/uhn/hapi/fhir/docs/server_jpa/configuration.md @@ -74,6 +74,37 @@ myDaoConfig.getTreatReferencesAsLogical().add("http://mysystem.com/ValueSet/cats myDaoConfig.getTreatReferencesAsLogical().add("http://mysystem.com/mysystem-vs-*"); ``` +## Referential Integrity + +Enabling referential integrity will ensure that reference values exist in the database. If the referenced entity does +not exist, the server will return an error. + +It is important to note that referential integrity is not enforced on database-level. The referential integrity check +*only* validates references that are indexed by a `SearchParameter`. + +### Enabling Referential Integrity +Referential integrity can be configured on two levels: `write` and `delete`. + +#### JPA Server +```java +@Bean +public DaoConfig daoConfig() { + DaoConfig retVal = new DaoConfig(); + // ... other config ... + retVal.setEnforceReferentialIntegrityOnWrite(true); + retVal.setEnforceReferentialIntegrityOnDelete(true); + return retVal; +} +``` +#### JPA Server Starter +This can be easily enabled in the `application.yaml` file at the following paths: +```yaml +hapi: + fhir: + enforce_referential_integrity_on_write: true + enforce_referential_integrity_on_delete: true +``` + # Search Result Caching By default, search results will be cached for one minute. This means that if a client performs a search for Patient?name=smith and gets back 500 results, if a client performs the same search within 60000 milliseconds the previously loaded search results will be returned again. This also means that any new Patient resources named "Smith" within the last minute will not be reflected in the results. From 9665476c00779e358205a6b4b14d7b8926247e75 Mon Sep 17 00:00:00 2001 From: JorisHeadease Date: Tue, 31 Jan 2023 14:41:41 +0100 Subject: [PATCH 5/9] =?UTF-8?q?The=20`OverridePathBasedReferentialIntegrit?= =?UTF-8?q?yForDeletesInterceptor`=20now=20=E2=80=A6=20(#4483)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * The `OverridePathBasedReferentialIntegrityForDeletesInterceptor` now works for a multitenant enabled server. The `RequestDetails` weren't set while requesting the conflicting resource via the `DaoRegistry`. * Add credit --------- Co-authored-by: Joris Scharp Co-authored-by: James Agnew --- ...rityForDeletesInterceptor-partitioned.yaml | 5 + ...rentialIntegrityForDeletesInterceptor.java | 5 +- ...ialIntegrityForDeletesInterceptorTest.java | 145 ++++++++++++++++++ pom.xml | 3 + 4 files changed, 156 insertions(+), 2 deletions(-) create mode 100644 hapi-fhir-docs/src/main/resources/ca/uhn/hapi/fhir/changelog/6_6_0/4483-OverridePathBasedReferentialIntegrityForDeletesInterceptor-partitioned.yaml create mode 100644 hapi-fhir-jpaserver-test-r4/src/test/java/ca/uhn/fhir/jpa/interceptor/MultitenantOverridePathBasedReferentialIntegrityForDeletesInterceptorTest.java diff --git a/hapi-fhir-docs/src/main/resources/ca/uhn/hapi/fhir/changelog/6_6_0/4483-OverridePathBasedReferentialIntegrityForDeletesInterceptor-partitioned.yaml b/hapi-fhir-docs/src/main/resources/ca/uhn/hapi/fhir/changelog/6_6_0/4483-OverridePathBasedReferentialIntegrityForDeletesInterceptor-partitioned.yaml new file mode 100644 index 00000000000..fc5877b09d0 --- /dev/null +++ b/hapi-fhir-docs/src/main/resources/ca/uhn/hapi/fhir/changelog/6_6_0/4483-OverridePathBasedReferentialIntegrityForDeletesInterceptor-partitioned.yaml @@ -0,0 +1,5 @@ +--- +type: fix +issue: 4483 +title: "The OverridePathBasedReferentialIntegrityForDeletesInterceptor now works on partitioned + servers. Thanks to GitHub user @JorisHeadease for the pull request!" diff --git a/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/interceptor/OverridePathBasedReferentialIntegrityForDeletesInterceptor.java b/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/interceptor/OverridePathBasedReferentialIntegrityForDeletesInterceptor.java index 7d9bab00e83..ea80b7527bc 100644 --- a/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/interceptor/OverridePathBasedReferentialIntegrityForDeletesInterceptor.java +++ b/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/interceptor/OverridePathBasedReferentialIntegrityForDeletesInterceptor.java @@ -29,6 +29,7 @@ import ca.uhn.fhir.jpa.api.dao.DaoRegistry; import ca.uhn.fhir.jpa.api.model.DeleteConflict; import ca.uhn.fhir.jpa.api.model.DeleteConflictList; import ca.uhn.fhir.model.primitive.IdDt; +import ca.uhn.fhir.rest.api.server.RequestDetails; import org.hl7.fhir.instance.model.api.IBaseReference; import org.hl7.fhir.instance.model.api.IBaseResource; import org.slf4j.Logger; @@ -99,7 +100,7 @@ public class OverridePathBasedReferentialIntegrityForDeletesInterceptor { * Interceptor hook method. Do not invoke directly. */ @Hook(value = Pointcut.STORAGE_PRESTORAGE_DELETE_CONFLICTS, order = CascadingDeleteInterceptor.OVERRIDE_PATH_BASED_REF_INTEGRITY_INTERCEPTOR_ORDER) - public void handleDeleteConflicts(DeleteConflictList theDeleteConflictList) { + public void handleDeleteConflicts(DeleteConflictList theDeleteConflictList, RequestDetails requestDetails) { for (DeleteConflict nextConflict : theDeleteConflictList) { ourLog.info("Ignoring referential integrity deleting {} - Referred to from {} at path {}", nextConflict.getTargetId(), nextConflict.getSourceId(), nextConflict.getSourcePath()); @@ -107,7 +108,7 @@ public class OverridePathBasedReferentialIntegrityForDeletesInterceptor { IdDt targetId = nextConflict.getTargetId(); String targetIdValue = targetId.toVersionless().getValue(); - IBaseResource sourceResource = myDaoRegistry.getResourceDao(sourceId.getResourceType()).read(sourceId); + IBaseResource sourceResource = myDaoRegistry.getResourceDao(sourceId.getResourceType()).read(sourceId, requestDetails); IFhirPath fhirPath = myFhirContext.newFhirPath(); for (String nextPath : myPaths) { diff --git a/hapi-fhir-jpaserver-test-r4/src/test/java/ca/uhn/fhir/jpa/interceptor/MultitenantOverridePathBasedReferentialIntegrityForDeletesInterceptorTest.java b/hapi-fhir-jpaserver-test-r4/src/test/java/ca/uhn/fhir/jpa/interceptor/MultitenantOverridePathBasedReferentialIntegrityForDeletesInterceptorTest.java new file mode 100644 index 00000000000..43040fd6f32 --- /dev/null +++ b/hapi-fhir-jpaserver-test-r4/src/test/java/ca/uhn/fhir/jpa/interceptor/MultitenantOverridePathBasedReferentialIntegrityForDeletesInterceptorTest.java @@ -0,0 +1,145 @@ +package ca.uhn.fhir.jpa.interceptor; + +import ca.uhn.fhir.jpa.model.config.PartitionSettings; +import ca.uhn.fhir.jpa.provider.r4.BaseMultitenantResourceProviderR4Test; +import ca.uhn.fhir.jpa.searchparam.SearchParameterMap; +import ca.uhn.fhir.rest.api.server.IBundleProvider; +import ca.uhn.fhir.rest.api.server.RequestDetails; +import ca.uhn.fhir.rest.api.server.SystemRequestDetails; +import ca.uhn.fhir.rest.param.ReferenceParam; +import ca.uhn.fhir.rest.server.exceptions.ResourceGoneException; +import ca.uhn.fhir.rest.server.exceptions.ResourceVersionConflictException; +import org.hl7.fhir.r4.model.AuditEvent; +import org.hl7.fhir.r4.model.IdType; +import org.hl7.fhir.r4.model.Patient; +import org.junit.jupiter.api.AfterEach; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; +import org.springframework.beans.factory.annotation.Autowired; + +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertFalse; +import static org.junit.jupiter.api.Assertions.fail; + +/** + *

Multitenant test version of {@link OverridePathBasedReferentialIntegrityForDeletesInterceptorTest}.

+ * + *

Ensures the tenant is properly propagated down to the {@link ca.uhn.fhir.jpa.api.dao.DaoRegistry} when requesting + * the conflicting resource.

+ * + *

This test runs a subset of tests from {@link OverridePathBasedReferentialIntegrityForDeletesInterceptorTest} + * against the {@link BaseMultitenantResourceProviderR4Test}

+ */ +public class MultitenantOverridePathBasedReferentialIntegrityForDeletesInterceptorTest extends BaseMultitenantResourceProviderR4Test { + + @Autowired + private OverridePathBasedReferentialIntegrityForDeletesInterceptor mySvc; + + @Autowired + private CascadingDeleteInterceptor myCascadingDeleteInterceptor; + + RequestDetails requestDetails = new SystemRequestDetails(); + + @BeforeEach + public void beforeEach() { + requestDetails.setTenantId(TENANT_A); + } + + @AfterEach + public void after() throws Exception { + myPartitionSettings.setAllowReferencesAcrossPartitions(PartitionSettings.CrossPartitionReferenceMode.NOT_ALLOWED); + assertFalse(myPartitionSettings.isAllowUnqualifiedCrossPartitionReference()); + + myInterceptorRegistry.unregisterInterceptor(mySvc); + mySvc.clearPaths(); + + super.after(); + } + + @Test + public void testAllowDelete() { + + mySvc.addPath("AuditEvent.agent.who"); + myInterceptorRegistry.registerInterceptor(mySvc); + + Patient patient = new Patient(); + patient.setId("P"); + patient.setActive(true); + myPatientDao.update(patient, requestDetails); + + AuditEvent audit = new AuditEvent(); + audit.setId("A"); + audit.addAgent().getWho().setReference("Patient/P"); + myAuditEventDao.update(audit, requestDetails); + + // Delete should proceed + myPatientDao.delete(new IdType("Patient/P"), requestDetails); + + // Make sure we're deleted + try { + myPatientDao.read(new IdType("Patient/P"), requestDetails); + fail(); + } catch (ResourceGoneException e) { + // good + } + + // Search should still work + IBundleProvider searchOutcome = myAuditEventDao.search(SearchParameterMap.newSynchronous(AuditEvent.SP_AGENT, new ReferenceParam("Patient/P")), requestDetails); + assertEquals(1, searchOutcome.size()); + } + + @Test + public void testWrongPath() { + mySvc.addPath("AuditEvent.identifier"); + mySvc.addPath("Patient.agent.who"); + myInterceptorRegistry.registerInterceptor(mySvc); + + Patient patient = new Patient(); + patient.setId("P"); + patient.setActive(true); + myPatientDao.update(patient, requestDetails); + + AuditEvent audit = new AuditEvent(); + audit.setId("A"); + audit.addAgent().getWho().setReference("Patient/P"); + myAuditEventDao.update(audit, requestDetails); + + // Delete should proceed + try { + myPatientDao.delete(new IdType("Patient/P"), requestDetails); + fail(); + } catch (ResourceVersionConflictException e) { + // good + } + + + } + + @Test + public void testCombineWithCascadeDeleteInterceptor() { + try { + myInterceptorRegistry.registerInterceptor(myCascadingDeleteInterceptor); + + mySvc.addPath("AuditEvent.agent.who"); + myInterceptorRegistry.registerInterceptor(mySvc); + + Patient patient = new Patient(); + patient.setId("P"); + patient.setActive(true); + myPatientDao.update(patient, requestDetails); + + AuditEvent audit = new AuditEvent(); + audit.setId("A"); + audit.addAgent().getWho().setReference("Patient/P"); + myAuditEventDao.update(audit, requestDetails); + + // Delete should proceed + myPatientDao.delete(new IdType("Patient/P"), requestDetails); + + } finally { + myInterceptorRegistry.unregisterInterceptor(myCascadingDeleteInterceptor); + } + + } + +} diff --git a/pom.xml b/pom.xml index 000451e375f..50cbf482b70 100644 --- a/pom.xml +++ b/pom.xml @@ -852,6 +852,9 @@ John D'Amore More Informatics + + JorisHeadease + From 64d776ac0ebe1453ccd7da449a480f0a11d21e36 Mon Sep 17 00:00:00 2001 From: Mark Iantorno Date: Fri, 3 Feb 2023 09:40:32 -0500 Subject: [PATCH 6/9] Checkstyle cleanup (#4501) * cleaning up checkstyle files * added exlusions for files at base project level so checkstyle doesn't error out * duplicate error code from merge * One more fix for #4467 * changing lifecycle goal for all module checkstyle check * moving checkstyle to base pom file, changing exectution phase on base check, cleaning dependency, resolving duplicate error code * wip * trying to figure out why pipeline cannot copy files * removing modules that don't actually need to be built. * I messed up the version * missing model --------- Co-authored-by: James Agnew --- azure-pipelines.yml | 4 - hapi-deployable-pom/pom.xml | 33 +- hapi-fhir-base/pom.xml | 56 ++++ .../ca/uhn/fhir/validation/FhirValidator.java | 2 +- hapi-fhir-checkstyle/pom.xml | 65 ++++ .../hapi-base-checkstyle-suppression.xml | 16 +- .../src/checkstyle/hapi-base-checkstyle.xml | 41 +++ .../uhn/fhir/checks/HapiErrorCodeCheck.java | 50 ++- .../fhir/checks/HapiErrorCodeCheckTest.java | 7 +- .../src/test/resources/BadClass.java | 9 +- .../java/ca/uhn/fhir/cli/BaseCommand.java | 2 +- .../cli/ValidationSupportChainCreator.java | 2 +- .../okhttp/client/OkHttpRestfulClient.java | 4 +- .../CircularQueueCaptureQueriesListener.java | 1 + .../export/svc/JpaBulkExportProcessor.java | 2 +- .../search/ExtendedHSearchClauseBuilder.java | 4 +- .../jpa/util/WebsocketSubscriptionClient.java | 1 + .../mdm/rules/matcher/NicknameMatcher.java | 2 +- .../provider/HashMapResourceProvider.java | 10 +- .../ServerCapabilityStatementProvider.java | 4 +- .../jobs/export/FetchResourceIdsStep.java | 2 +- .../batch2/jobs/export/WriteBinaryStep.java | 2 +- .../jobs/services/Batch2JobRunnerImpl.java | 2 +- .../ServerCapabilityStatementProvider.java | 2 +- .../fhir/r5/hapi/ctx/HapiWorkerContext.java | 2 +- .../test/utilities/RestServerDstu3Helper.java | 4 +- .../VersionSpecificWorkerContextWrapper.java | 8 +- hapi-tinder-test/pom.xml | 40 --- pom.xml | 308 +++++++----------- src/checkstyle/checkstyle.xml | 192 ----------- src/checkstyle/checkstyle_config_nofixmes.xml | 21 -- 31 files changed, 366 insertions(+), 532 deletions(-) rename src/checkstyle/checkstyle_suppressions.xml => hapi-fhir-checkstyle/src/checkstyle/hapi-base-checkstyle-suppression.xml (50%) create mode 100644 hapi-fhir-checkstyle/src/checkstyle/hapi-base-checkstyle.xml delete mode 100644 src/checkstyle/checkstyle.xml delete mode 100644 src/checkstyle/checkstyle_config_nofixmes.xml diff --git a/azure-pipelines.yml b/azure-pipelines.yml index 13987de4279..3278f295938 100644 --- a/azure-pipelines.yml +++ b/azure-pipelines.yml @@ -80,16 +80,12 @@ stages: module: hapi-fhir-server-mdm - name: hapi_fhir_server_openapi module: hapi-fhir-server-openapi - - name: hapi_fhir_serviceloaders - module: hapi-fhir-serviceloaders - name: hapi_fhir_caching_api module: hapi-fhir-serviceloaders/hapi-fhir-caching-api - name: hapi_fhir_caching_caffeine module: hapi-fhir-serviceloaders/hapi-fhir-caching-caffeine - name: hapi_fhir_caching_guava module: hapi-fhir-serviceloaders/hapi-fhir-caching-guava - - name: hapi_fhir_caching_testing - module: hapi-fhir-serviceloaders/hapi-fhir-caching-testing - name: hapi_fhir_spring_boot_autoconfigure module: hapi-fhir-spring-boot/hapi-fhir-spring-boot-autoconfigure - name: hapi_fhir_spring_boot_sample_server_jersey diff --git a/hapi-deployable-pom/pom.xml b/hapi-deployable-pom/pom.xml index 2bb90c5f35b..78b4a363ebd 100644 --- a/hapi-deployable-pom/pom.xml +++ b/hapi-deployable-pom/pom.xml @@ -1,7 +1,8 @@ - - 4.0.0 + + 4.0.0 - + ca.uhn.hapi.fhir hapi-fhir 6.5.0-SNAPSHOT @@ -13,9 +14,6 @@ HAPI FHIR - Deployable Artifact Parent POM - - - @@ -120,27 +118,6 @@ - - org.apache.maven.plugins - maven-checkstyle-plugin - - - process-sources - - check - - - true - true - ${maven.multiModuleProjectDirectory}/src/checkstyle/checkstyle_suppressions.xml - true - true - true - ${maven.multiModuleProjectDirectory}/src/checkstyle/checkstyle.xml - - - - @@ -208,7 +185,6 @@ package - jar @@ -252,5 +228,4 @@ - diff --git a/hapi-fhir-base/pom.xml b/hapi-fhir-base/pom.xml index 8a5bc10ca9b..1a12470d99a 100644 --- a/hapi-fhir-base/pom.xml +++ b/hapi-fhir-base/pom.xml @@ -196,6 +196,62 @@ + + org.apache.maven.plugins + maven-antrun-plugin + 1.8 + + + + + + + true + + + delete-module-cache-file + validate + + run + + + + + + org.apache.maven.plugins + maven-checkstyle-plugin + ${maven_checkstyle_version} + + + ${maven.multiModuleProjectDirectory}/hapi-fhir-checkstyle/src/checkstyle/hapi-base-checkstyle.xml + + ${maven.multiModuleProjectDirectory}/hapi-fhir-checkstyle/src/checkstyle/hapi-base-checkstyle-suppression.xml + UTF-8 + true + + true + + + hapi-single-module-checkstyle + validate + + check + + + + + + ca.uhn.hapi.fhir + hapi-fhir-checkstyle + ${project.version} + + + com.puppycrawl.tools + checkstyle + ${checkstyle_version} + + + diff --git a/hapi-fhir-base/src/main/java/ca/uhn/fhir/validation/FhirValidator.java b/hapi-fhir-base/src/main/java/ca/uhn/fhir/validation/FhirValidator.java index b22b8eeefdc..d5eb604015f 100644 --- a/hapi-fhir-base/src/main/java/ca/uhn/fhir/validation/FhirValidator.java +++ b/hapi-fhir-base/src/main/java/ca/uhn/fhir/validation/FhirValidator.java @@ -333,7 +333,7 @@ public class FhirValidator { retval.addAll(messages); } } catch (InterruptedException | ExecutionException exp) { - throw new InternalErrorException(Msg.code(1975) + exp); + throw new InternalErrorException(Msg.code(2246) + exp); } return retval; } diff --git a/hapi-fhir-checkstyle/pom.xml b/hapi-fhir-checkstyle/pom.xml index 405d85e54ec..afbd19e7ea4 100644 --- a/hapi-fhir-checkstyle/pom.xml +++ b/hapi-fhir-checkstyle/pom.xml @@ -18,6 +18,7 @@ com.puppycrawl.tools checkstyle + ${checkstyle_version} commons-io @@ -34,6 +35,31 @@ + + + + + org.apache.maven.plugins + maven-checkstyle-plugin + 3.2.0 + + + com.puppycrawl.tools + checkstyle + ${checkstyle_version} + + + ca.uhn.hapi.fhir + hapi-fhir-checkstyle + + ${project.version} + + + + + + + @@ -75,5 +101,44 @@ + + CI + + + + org.apache.maven.plugins + maven-checkstyle-plugin + ${maven_checkstyle_version} + + **/osgi/**/*, **/.mvn/**/*, **/.mvn_/**/* + + + + ${maven.multiModuleProjectDirectory}/ + + + ${maven.multiModuleProjectDirectory}/hapi-fhir-checkstyle/src/checkstyle/hapi-base-checkstyle.xml + + ${maven.multiModuleProjectDirectory}/hapi-fhir-checkstyle/src/checkstyle/hapi-base-checkstyle-suppression.xml + UTF-8 + true + + + + checkstyle-across-all-modules + install + + check + + + + hapi-single-module-checkstyle + none + + + + + + diff --git a/src/checkstyle/checkstyle_suppressions.xml b/hapi-fhir-checkstyle/src/checkstyle/hapi-base-checkstyle-suppression.xml similarity index 50% rename from src/checkstyle/checkstyle_suppressions.xml rename to hapi-fhir-checkstyle/src/checkstyle/hapi-base-checkstyle-suppression.xml index 7c1de5e4e4b..910deb076bc 100644 --- a/src/checkstyle/checkstyle_suppressions.xml +++ b/hapi-fhir-checkstyle/src/checkstyle/hapi-base-checkstyle-suppression.xml @@ -1,10 +1,18 @@ - + "-//Checkstyle//DTD SuppressionFilter Configuration 1.2//EN" + "https://checkstyle.org/dtds/suppressions_1_2.dtd"> + + + + + + + + + @@ -16,4 +24,6 @@ + + diff --git a/hapi-fhir-checkstyle/src/checkstyle/hapi-base-checkstyle.xml b/hapi-fhir-checkstyle/src/checkstyle/hapi-base-checkstyle.xml new file mode 100644 index 00000000000..5ff02a4549d --- /dev/null +++ b/hapi-fhir-checkstyle/src/checkstyle/hapi-base-checkstyle.xml @@ -0,0 +1,41 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/hapi-fhir-checkstyle/src/main/java/ca/uhn/fhir/checks/HapiErrorCodeCheck.java b/hapi-fhir-checkstyle/src/main/java/ca/uhn/fhir/checks/HapiErrorCodeCheck.java index 60b1cacf187..6a22f208d72 100644 --- a/hapi-fhir-checkstyle/src/main/java/ca/uhn/fhir/checks/HapiErrorCodeCheck.java +++ b/hapi-fhir-checkstyle/src/main/java/ca/uhn/fhir/checks/HapiErrorCodeCheck.java @@ -1,6 +1,6 @@ package ca.uhn.fhir.checks; -import com.puppycrawl.tools.checkstyle.StatelessCheck; +import com.puppycrawl.tools.checkstyle.FileStatefulCheck; import com.puppycrawl.tools.checkstyle.api.AbstractCheck; import com.puppycrawl.tools.checkstyle.api.DetailAST; import com.puppycrawl.tools.checkstyle.api.TokenTypes; @@ -9,15 +9,13 @@ import org.slf4j.LoggerFactory; import java.util.HashMap; import java.util.Map; +import java.util.Set; -/** - * mvn -P CI checkstyle:check - */ -@StatelessCheck +@FileStatefulCheck public final class HapiErrorCodeCheck extends AbstractCheck { private static final Logger ourLog = LoggerFactory.getLogger(HapiErrorCodeCheck.class); - private static final Map ourCodesUsed = new HashMap<>(); + private static final ErrorCodeCache ourCache = ErrorCodeCache.INSTANCE; @Override public int[] getDefaultTokens() { @@ -42,10 +40,6 @@ public final class HapiErrorCodeCheck extends AbstractCheck { } private void validateMessageCode(DetailAST theAst) { - // TODO KHS this should be done in the checkstyle plugin pom config, not here - if (getFileContents().getFileName().contains("/generated-sources/")) { - return; - } DetailAST instantiation = theAst.getFirstChild().getFirstChild(); // We only expect message codes on new exception instantiations if (TokenTypes.LITERAL_NEW != instantiation.getType()) { @@ -68,14 +62,13 @@ public final class HapiErrorCodeCheck extends AbstractCheck { DetailAST numberNode = msgNode.getParent().getNextSibling().getFirstChild().getFirstChild(); if (TokenTypes.NUM_INT == numberNode.getType()) { Integer code = Integer.valueOf(numberNode.getText()); - if (ourCodesUsed.containsKey(code)) { + if (ourCache.containsKey(code)) { log(theAst.getLineNo(), "Two different exception messages call Msg.code(" + - code + - "). Each thrown exception throw call Msg.code() with a different code. " + - "Previously found at: " + ourCodesUsed.get(code)); + code + "). \nEach thrown exception must call Msg.code() with a different code. " + + "\nPreviously found at: " + ourCache.get(code)); } else { - String location = getFileContents().getFileName() + ":" + instantiation.getLineNo() + ":" + instantiation.getColumnNo() + "(" + code + ")"; - ourCodesUsed.put(code, location); + String location = getFilePath() + ":" + instantiation.getLineNo() + ":" + instantiation.getColumnNo() + "(" + code + ")"; + ourCache.put(code, location); } } else { log(theAst.getLineNo(), "Called Msg.code() with a non-integer argument"); @@ -110,5 +103,30 @@ public final class HapiErrorCodeCheck extends AbstractCheck { } return null; } + + public enum ErrorCodeCache { + INSTANCE; + + private static final Map ourCodesUsed = new HashMap<>(); + + ErrorCodeCache() { + } + + public boolean containsKey(Integer s) { + return ourCodesUsed.containsKey(s); + } + + public String get(Integer i) { + return ourCodesUsed.get(i); + } + + public String put(Integer code, String location) { + return ourCodesUsed.put(code, location); + } + + public Set keySet() { + return ourCodesUsed.keySet(); + } + } } diff --git a/hapi-fhir-checkstyle/src/test/java/ca/uhn/fhir/checks/HapiErrorCodeCheckTest.java b/hapi-fhir-checkstyle/src/test/java/ca/uhn/fhir/checks/HapiErrorCodeCheckTest.java index fb0ae2bf889..698251a669d 100644 --- a/hapi-fhir-checkstyle/src/test/java/ca/uhn/fhir/checks/HapiErrorCodeCheckTest.java +++ b/hapi-fhir-checkstyle/src/test/java/ca/uhn/fhir/checks/HapiErrorCodeCheckTest.java @@ -44,12 +44,13 @@ class HapiErrorCodeCheckTest { // validate String[] errorLines = errors.toString().split("\r?\n"); Arrays.stream(errorLines).forEach(ourLog::info); - assertEquals(2, errorLines.length); + assertEquals(4, errorLines.length); assertThat(errorLines[0], startsWith("[ERROR] ")); assertThat(errorLines[0], endsWith("BadClass.java:7: Exception thrown that does not call Msg.code() [HapiErrorCode]")); assertThat(errorLines[1], startsWith("[ERROR] ")); - assertThat(errorLines[1], containsString("BadClass.java:11: Two different exception messages call Msg.code(2). Each thrown exception throw call Msg.code() with a different code.")); - assertThat(errorLines[1], containsString("BadClass.java:9:9")); + assertThat(errorLines[1], containsString("Two different exception messages call Msg.code(2258).")); + assertThat(errorLines[2], containsString("Each thrown exception must call Msg.code() with a different code.")); + assertThat(errorLines[3], containsString("Previously found at:")); } private Checker buildChecker() throws CheckstyleException { diff --git a/hapi-fhir-checkstyle/src/test/resources/BadClass.java b/hapi-fhir-checkstyle/src/test/resources/BadClass.java index f0470ffb221..acd57340891 100644 --- a/hapi-fhir-checkstyle/src/test/resources/BadClass.java +++ b/hapi-fhir-checkstyle/src/test/resources/BadClass.java @@ -2,16 +2,15 @@ public class BadClass { public void init() throws Exception { int i = 1; if (i == 0) { - throw new MessagingException(theMessage, Msg.code(6) + "Failure handling subscription payload", e); + throw new MessagingException(theMessage, Msg.code(2259) + "Failure handling subscription payload", e); } else if (i == 1) { throw new RuntimeException("nocode"); } else if (i == 2) { - throw new RuntimeException(Msg.code(2) + "duplicate code"); + throw new RuntimeException(Msg.code(2258) + "duplicate code"); } else if (i == 3) { - throw new RuntimeException(Msg.code(2) + "duplicate code"); - } else if (i == 4) { - throw new RuntimeException(Msg.code(1) + "good"); + throw new RuntimeException(Msg.code(2258) + "duplicate code"); } + ClassCastException e = new ClassCastException(); throwException(i, e); } diff --git a/hapi-fhir-cli/hapi-fhir-cli-api/src/main/java/ca/uhn/fhir/cli/BaseCommand.java b/hapi-fhir-cli/hapi-fhir-cli-api/src/main/java/ca/uhn/fhir/cli/BaseCommand.java index bab9aae7936..cfa243dd0d4 100644 --- a/hapi-fhir-cli/hapi-fhir-cli-api/src/main/java/ca/uhn/fhir/cli/BaseCommand.java +++ b/hapi-fhir-cli/hapi-fhir-cli-api/src/main/java/ca/uhn/fhir/cli/BaseCommand.java @@ -531,7 +531,7 @@ public abstract class BaseCommand implements Comparable { return Optional.of(new TlsAuthentication(keyStoreInfo, trustStoreInfo)); } catch(Exception e){ - throw new RuntimeException(Msg.code(2115)+"Could not create TLS configuration options", e); + throw new RuntimeException(Msg.code(2253)+"Could not create TLS configuration options", e); } } diff --git a/hapi-fhir-cli/hapi-fhir-cli-api/src/main/java/ca/uhn/fhir/cli/ValidationSupportChainCreator.java b/hapi-fhir-cli/hapi-fhir-cli-api/src/main/java/ca/uhn/fhir/cli/ValidationSupportChainCreator.java index 4224901ba1e..1eb6407a568 100644 --- a/hapi-fhir-cli/hapi-fhir-cli-api/src/main/java/ca/uhn/fhir/cli/ValidationSupportChainCreator.java +++ b/hapi-fhir-cli/hapi-fhir-cli-api/src/main/java/ca/uhn/fhir/cli/ValidationSupportChainCreator.java @@ -48,7 +48,7 @@ public class ValidationSupportChainCreator { chain.addValidationSupport(localFileValidationSupport); chain.addValidationSupport(new SnapshotGeneratingValidationSupport(ctx)); } catch (IOException e) { - throw new RuntimeException(Msg.code(2207) + "Failed to load local profile.", e); + throw new RuntimeException(Msg.code(2254) + "Failed to load local profile.", e); } } if (commandLine.hasOption("r")) { diff --git a/hapi-fhir-client-okhttp/src/main/java/ca/uhn/fhir/okhttp/client/OkHttpRestfulClient.java b/hapi-fhir-client-okhttp/src/main/java/ca/uhn/fhir/okhttp/client/OkHttpRestfulClient.java index 48dc93279d5..5d4acce5b4a 100644 --- a/hapi-fhir-client-okhttp/src/main/java/ca/uhn/fhir/okhttp/client/OkHttpRestfulClient.java +++ b/hapi-fhir-client-okhttp/src/main/java/ca/uhn/fhir/okhttp/client/OkHttpRestfulClient.java @@ -89,13 +89,13 @@ public class OkHttpRestfulClient implements IHttpClient { } private RequestBody createPostBody(String theContents, String theContentType) { - return RequestBody.create(MediaType.parse(theContentType), theContents); + return RequestBody.create(MediaType.parse(theContentType), theContents); } @Override public IHttpRequest createParamRequest(FhirContext theContext, Map> theParams, EncodingEnum theEncoding) { initBaseRequest(theContext, theEncoding, getFormBodyFromParams(theParams)); - return myRequest; + return myRequest; } private RequestBody getFormBodyFromParams(Map> queryParams) { diff --git a/hapi-fhir-jpa/src/main/java/ca/uhn/fhir/jpa/util/CircularQueueCaptureQueriesListener.java b/hapi-fhir-jpa/src/main/java/ca/uhn/fhir/jpa/util/CircularQueueCaptureQueriesListener.java index bc558009870..b41dc31d3fe 100644 --- a/hapi-fhir-jpa/src/main/java/ca/uhn/fhir/jpa/util/CircularQueueCaptureQueriesListener.java +++ b/hapi-fhir-jpa/src/main/java/ca/uhn/fhir/jpa/util/CircularQueueCaptureQueriesListener.java @@ -20,6 +20,7 @@ package ca.uhn.fhir.jpa.util; * #L% */ +import ca.uhn.fhir.i18n.Msg; import ca.uhn.fhir.util.StopWatch; import com.google.common.collect.Queues; import net.ttddyy.dsproxy.support.ProxyDataSourceBuilder; diff --git a/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/bulk/export/svc/JpaBulkExportProcessor.java b/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/bulk/export/svc/JpaBulkExportProcessor.java index 0ad04a80b8e..de1aa0c08de 100644 --- a/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/bulk/export/svc/JpaBulkExportProcessor.java +++ b/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/bulk/export/svc/JpaBulkExportProcessor.java @@ -549,7 +549,7 @@ public class JpaBulkExportProcessor implements IBulkExportProcessor { Optional oPatientSearchParam = SearchParameterUtil.getOnlyPatientSearchParamForResourceType(myContext, theResource.fhirType()); if (!oPatientSearchParam.isPresent()) { String errorMessage = String.format("[%s] has no search parameters that are for patients, so it is invalid for Group Bulk Export!", theResource.fhirType()); - throw new IllegalArgumentException(Msg.code(2103) + errorMessage); + throw new IllegalArgumentException(Msg.code(2242) + errorMessage); } else { return oPatientSearchParam.get(); } diff --git a/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/dao/search/ExtendedHSearchClauseBuilder.java b/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/dao/search/ExtendedHSearchClauseBuilder.java index 824709ccfa7..069288c8d99 100644 --- a/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/dao/search/ExtendedHSearchClauseBuilder.java +++ b/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/dao/search/ExtendedHSearchClauseBuilder.java @@ -452,7 +452,7 @@ public class ExtendedHSearchClauseBuilder { booleanStep.minimumShouldMatchNumber(1); return booleanStep; } - throw new IllegalArgumentException(Msg.code(2025) + "Date search param does not support prefix of type: " + prefix); + throw new IllegalArgumentException(Msg.code(2255) + "Date search param does not support prefix of type: " + prefix); } private PredicateFinalStep generateDateInstantSearchTerms(DateParam theDateParam, PathContext theSpContext) { @@ -496,7 +496,7 @@ public class ExtendedHSearchClauseBuilder { return ((SearchPredicateFactory) theSpContext).range().field(lowerInstantField).atMost(upperBoundAsInstant); } - throw new IllegalArgumentException(Msg.code(2026) + "Date search param does not support prefix of type: " + prefix); + throw new IllegalArgumentException(Msg.code(2256) + "Date search param does not support prefix of type: " + prefix); } diff --git a/hapi-fhir-jpaserver-test-utilities/src/main/java/ca/uhn/fhir/jpa/util/WebsocketSubscriptionClient.java b/hapi-fhir-jpaserver-test-utilities/src/main/java/ca/uhn/fhir/jpa/util/WebsocketSubscriptionClient.java index 95c7600b0fa..73c737a9ee9 100644 --- a/hapi-fhir-jpaserver-test-utilities/src/main/java/ca/uhn/fhir/jpa/util/WebsocketSubscriptionClient.java +++ b/hapi-fhir-jpaserver-test-utilities/src/main/java/ca/uhn/fhir/jpa/util/WebsocketSubscriptionClient.java @@ -20,6 +20,7 @@ package ca.uhn.fhir.jpa.util; * #L% */ +import ca.uhn.fhir.i18n.Msg; import ca.uhn.fhir.jpa.model.entity.ModelConfig; import ca.uhn.fhir.jpa.subscription.SocketImplementation; import ca.uhn.fhir.rest.api.EncodingEnum; diff --git a/hapi-fhir-server-mdm/src/main/java/ca/uhn/fhir/mdm/rules/matcher/NicknameMatcher.java b/hapi-fhir-server-mdm/src/main/java/ca/uhn/fhir/mdm/rules/matcher/NicknameMatcher.java index 8e3a3c5fd24..685e84bf5fa 100644 --- a/hapi-fhir-server-mdm/src/main/java/ca/uhn/fhir/mdm/rules/matcher/NicknameMatcher.java +++ b/hapi-fhir-server-mdm/src/main/java/ca/uhn/fhir/mdm/rules/matcher/NicknameMatcher.java @@ -35,7 +35,7 @@ public class NicknameMatcher implements IMdmStringMatcher { try { myNicknameSvc = new NicknameSvc(); } catch (IOException e) { - throw new ConfigurationException(Msg.code(2078) + "Unable to load nicknames", e); + throw new ConfigurationException(Msg.code(2234) + "Unable to load nicknames", e); } } diff --git a/hapi-fhir-server/src/main/java/ca/uhn/fhir/rest/server/provider/HashMapResourceProvider.java b/hapi-fhir-server/src/main/java/ca/uhn/fhir/rest/server/provider/HashMapResourceProvider.java index 045147d5aa0..9c982bb9c86 100644 --- a/hapi-fhir-server/src/main/java/ca/uhn/fhir/rest/server/provider/HashMapResourceProvider.java +++ b/hapi-fhir-server/src/main/java/ca/uhn/fhir/rest/server/provider/HashMapResourceProvider.java @@ -173,7 +173,7 @@ public class HashMapResourceProvider implements IResour TreeMap versions = myIdToVersionToResourceMap.get(theId.getIdPart()); if (versions == null || versions.isEmpty()) { - throw new ResourceNotFoundException(Msg.code(1979) + theId); + throw new ResourceNotFoundException(Msg.code(2250) + theId); } T deletedInstance = (T) myFhirContext.getResourceDefinition(myResourceType).newInstance(); @@ -240,7 +240,7 @@ public class HashMapResourceProvider implements IResour public synchronized List historyInstance(@IdParam IIdType theId, RequestDetails theRequestDetails) { LinkedList retVal = myIdToHistory.get(theId.getIdPart()); if (retVal == null) { - throw new ResourceNotFoundException(Msg.code(1980) + theId); + throw new ResourceNotFoundException(Msg.code(2248) + theId); } return fireInterceptorsAndFilterAsNeeded(retVal, theRequestDetails); @@ -255,7 +255,7 @@ public class HashMapResourceProvider implements IResour public synchronized T read(@IdParam IIdType theId, RequestDetails theRequestDetails) { TreeMap versions = myIdToVersionToResourceMap.get(theId.getIdPart()); if (versions == null || versions.isEmpty()) { - throw new ResourceNotFoundException(Msg.code(1981) + theId); + throw new ResourceNotFoundException(Msg.code(2247) + theId); } T retVal; @@ -271,14 +271,14 @@ public class HashMapResourceProvider implements IResour } if (retVal == null || ResourceMetadataKeyEnum.DELETED_AT.get(retVal) != null) { - throw new ResourceGoneException(Msg.code(1983) + theId); + throw new ResourceGoneException(Msg.code(2244) + theId); } myReadCount.incrementAndGet(); retVal = fireInterceptorsAndFilterAsNeeded(retVal, theRequestDetails); if (retVal == null) { - throw new ResourceNotFoundException(Msg.code(1984) + theId); + throw new ResourceNotFoundException(Msg.code(2243) + theId); } return retVal; } diff --git a/hapi-fhir-server/src/main/java/ca/uhn/fhir/rest/server/provider/ServerCapabilityStatementProvider.java b/hapi-fhir-server/src/main/java/ca/uhn/fhir/rest/server/provider/ServerCapabilityStatementProvider.java index ea3fc0946e9..c5eeb97e097 100644 --- a/hapi-fhir-server/src/main/java/ca/uhn/fhir/rest/server/provider/ServerCapabilityStatementProvider.java +++ b/hapi-fhir-server/src/main/java/ca/uhn/fhir/rest/server/provider/ServerCapabilityStatementProvider.java @@ -636,7 +636,7 @@ public class ServerCapabilityStatementProvider implements IServerConformanceProv @Read(typeName = "OperationDefinition") public IBaseResource readOperationDefinition(@IdParam IIdType theId, RequestDetails theRequestDetails) { if (theId == null || theId.hasIdPart() == false) { - throw new ResourceNotFoundException(Msg.code(1977) + theId); + throw new ResourceNotFoundException(Msg.code(2245) + theId); } RestfulServerConfiguration configuration = getServerConfiguration(); Bindings bindings = configuration.provideBindings(); @@ -650,7 +650,7 @@ public class ServerCapabilityStatementProvider implements IServerConformanceProv if (searchBindings != null && !searchBindings.isEmpty()) { return readOperationDefinitionForNamedSearch(searchBindings); } - throw new ResourceNotFoundException(Msg.code(1978) + theId); + throw new ResourceNotFoundException(Msg.code(2249) + theId); } private String getOperationId(IIdType theId) { diff --git a/hapi-fhir-storage-batch2-jobs/src/main/java/ca/uhn/fhir/batch2/jobs/export/FetchResourceIdsStep.java b/hapi-fhir-storage-batch2-jobs/src/main/java/ca/uhn/fhir/batch2/jobs/export/FetchResourceIdsStep.java index d6012ee366d..37f89c9fe2f 100644 --- a/hapi-fhir-storage-batch2-jobs/src/main/java/ca/uhn/fhir/batch2/jobs/export/FetchResourceIdsStep.java +++ b/hapi-fhir-storage-batch2-jobs/src/main/java/ca/uhn/fhir/batch2/jobs/export/FetchResourceIdsStep.java @@ -122,7 +122,7 @@ public class FetchResourceIdsStep implements IFirstJobStepWorker bindings) { diff --git a/hapi-fhir-structures-r5/src/main/java/org/hl7/fhir/r5/hapi/ctx/HapiWorkerContext.java b/hapi-fhir-structures-r5/src/main/java/org/hl7/fhir/r5/hapi/ctx/HapiWorkerContext.java index 0860043f5d0..6da640e9afa 100644 --- a/hapi-fhir-structures-r5/src/main/java/org/hl7/fhir/r5/hapi/ctx/HapiWorkerContext.java +++ b/hapi-fhir-structures-r5/src/main/java/org/hl7/fhir/r5/hapi/ctx/HapiWorkerContext.java @@ -106,7 +106,7 @@ public final class HapiWorkerContext extends I18nBase implements IWorkerContext @Override public Map getNSUrlMap() { - throw new UnsupportedOperationException(Msg.code(2107)); + throw new UnsupportedOperationException(Msg.code(2241)); } @Override diff --git a/hapi-fhir-test-utilities/src/main/java/ca/uhn/fhir/test/utilities/RestServerDstu3Helper.java b/hapi-fhir-test-utilities/src/main/java/ca/uhn/fhir/test/utilities/RestServerDstu3Helper.java index 303aee6a72c..1150bfa416f 100644 --- a/hapi-fhir-test-utilities/src/main/java/ca/uhn/fhir/test/utilities/RestServerDstu3Helper.java +++ b/hapi-fhir-test-utilities/src/main/java/ca/uhn/fhir/test/utilities/RestServerDstu3Helper.java @@ -66,7 +66,7 @@ public class RestServerDstu3Helper extends BaseRestServerHelper implements IPoin try { myRestServer.initialize(); } catch (ServletException e) { - throw new RuntimeException(Msg.code(2112)+"Failed to initialize server", e); + throw new RuntimeException(Msg.code(2252)+"Failed to initialize server", e); } } } @@ -294,7 +294,7 @@ public class RestServerDstu3Helper extends BaseRestServerHelper implements IPoin @Override public MethodOutcome update(T theResource, String theConditional, RequestDetails theRequestDetails) { if (myFailNextPut) { - throw new PreconditionFailedException(Msg.code(2113)+"Failed update operation"); + throw new PreconditionFailedException(Msg.code(2251)+"Failed update operation"); } return super.update(theResource, theConditional, theRequestDetails); } diff --git a/hapi-fhir-validation/src/main/java/org/hl7/fhir/common/hapi/validation/validator/VersionSpecificWorkerContextWrapper.java b/hapi-fhir-validation/src/main/java/org/hl7/fhir/common/hapi/validation/validator/VersionSpecificWorkerContextWrapper.java index 435aadb4977..6baac0f80c2 100644 --- a/hapi-fhir-validation/src/main/java/org/hl7/fhir/common/hapi/validation/validator/VersionSpecificWorkerContextWrapper.java +++ b/hapi-fhir-validation/src/main/java/org/hl7/fhir/common/hapi/validation/validator/VersionSpecificWorkerContextWrapper.java @@ -162,18 +162,18 @@ public class VersionSpecificWorkerContextWrapper extends I18nBase implements IWo @Override public IWorkerContextManager.IPackageLoadingTracker getPackageTracker() { - throw new UnsupportedOperationException(Msg.code(2108)); + throw new UnsupportedOperationException(Msg.code(2235)); } @Override public IWorkerContext setPackageTracker( IWorkerContextManager.IPackageLoadingTracker packageTracker) { - throw new UnsupportedOperationException(Msg.code(2114)); + throw new UnsupportedOperationException(Msg.code(2266)); } @Override public PackageInformation getPackageForUrl(String s) { - throw new UnsupportedOperationException(Msg.code(2109)); + throw new UnsupportedOperationException(Msg.code(2236)); } @Override @@ -410,7 +410,7 @@ public class VersionSpecificWorkerContextWrapper extends I18nBase implements IWo @Override public Map getNSUrlMap() { - throw new UnsupportedOperationException(Msg.code(2111)); + throw new UnsupportedOperationException(Msg.code(2265)); } @Override diff --git a/hapi-tinder-test/pom.xml b/hapi-tinder-test/pom.xml index 675bc8c3168..d0decbb3444 100644 --- a/hapi-tinder-test/pom.xml +++ b/hapi-tinder-test/pom.xml @@ -62,12 +62,6 @@ - - ca.uhn.hapi.fhir hapi-tinder-plugin @@ -136,37 +130,6 @@ - generalstructs @@ -383,8 +346,6 @@ - @@ -420,7 +381,6 @@ targetPackage="ca.uhn.test.ant.multi.r5" filenameSuffix="ResourceTest.java" projectHome="${project.basedir}/.." version="r5" includeResources="patient,organization" /> - - + + 5.6.84 + 1.0.3 + -Dfile.encoding=UTF-8 -Xmx2048m - 5.6.84 - 1.0.3 + + yyyy-MM-dd'T'HH:mm:ss'Z' + UTF-8 - -Dfile.encoding=UTF-8 -Xmx2048m + + ${user.home}/sites/hapi-fhir + ${user.home}/sites/scm/hapi-fhir - - yyyy-MM-dd'T'HH:mm:ss'Z' + + 1.2.0 + 4.2.5 + 1.2 + 3.1.1 + 10.6.0 + 3.2.0 + 2.12.1 + 1.15 + 1.21 + 1.10.0 + 2.11.0 + 3.12.0 + 1.2 + 10.14.2.0 + 2.10.0 + 4.8.1 + 0.7.9 + 31.0.1-jre + 2.8.9 + 2.2.11_1 + 2.3.1 + 2.3.0.1 + 3.0.0 + 4.2.0 + 3.0.3 + 10.0.12 + 3.0.2 + 5.9.1 + 0.50.40 + 9.4.0 + 5.6.12.Final + 6.1.6.Final + 1.4.4 + + 8.11.1 + 2.2 + 6.1.5.Final + 4.4.13 + 4.5.13 + 2.14.1 + 2.14.1 + 3.3.0 + 1.8 + 4.10.0 + 4.1.2 + 1.4 + 5.0.2.Final + 5.6.5 + 9.5.4 + 2.9.0 + 9.8.0-15 + 1.2_5 + 2.1.12 + 2.0.3 + 2.19.0 + 5.3.23 + 2021.2.2 + 4.3.3 + 2.7.5 + 1.2.2.RELEASE - UTF-8 + 3.1.4 + 1.17.1 + 3.0.14.RELEASE + 4.4.1 - - ${user.home}/sites/hapi-fhir - ${user.home}/sites/scm/hapi-fhir + + 1.6.0 - - 1.2.0 - 4.2.5 - 1.2 - 3.1.1 - 10.4 - 1.15 - 1.21 - 1.10.0 - 2.11.0 - 3.12.0 - 1.2 - 10.14.2.0 - - 2.10.0 - 4.8.1 - 0.7.9 - 31.0.1-jre - 2.8.9 - 2.2.11_1 - 2.3.1 - 2.3.0.1 - 3.0.0 - 4.2.0 - 3.0.3 - 10.0.12 - 3.0.2 - 5.9.1 - 0.50.40 - 9.4.0 - 5.6.12.Final - 6.1.6.Final - 1.4.4 - - 8.11.1 - 2.2 - 6.1.5.Final - 4.4.13 - 4.5.13 - 2.14.1 - 2.14.1 - 3.3.0 - 1.8 - 4.10.0 - 4.1.2 - 1.4 - 5.0.2.Final - 5.6.5 - 9.5.4 - 2.9.0 - 9.8.0-15 - 1.2_5 - 2.1.12 - 2.0.3 - 2.19.0 - 5.3.23 - 2021.2.2 - 4.3.3 - 2.7.5 - 1.2.2.RELEASE + UTF-8 + 1.0.1 - 3.1.4 - 1.17.1 - 3.0.14.RELEASE - 4.4.1 + 1.28.4 + + 2.4.0 + 2.3.0 + 2.3.0 - - 1.6.0 + + 5.4.1 + 11 + 11 + 11 + 17 + 17 + 17 - UTF-8 - 1.0.1 - - 1.28.4 - - 2.4.0 - 2.3.0 - 2.3.0 - - - 5.4.1 - 11 - 11 - 11 - 17 - 17 - 17 - - - + + @@ -2126,24 +2124,6 @@ - - org.apache.maven.plugins - maven-checkstyle-plugin - 3.2.0 - - - com.puppycrawl.tools - checkstyle - ${checkstyle_version} - - - ca.uhn.hapi.fhir - hapi-fhir-checkstyle - - 6.5.0-SNAPSHOT - - - org.apache.maven.plugins maven-resources-plugin @@ -2195,8 +2175,6 @@ 500m 2000m - - org.apache.maven.plugins @@ -2309,6 +2287,11 @@ jetty-maven-plugin ${jetty_version} + + org.apache.maven.plugins + maven-changes-plugin + ${maven_changes_version} + org.eluder.coveralls coveralls-maven-plugin @@ -2381,47 +2364,6 @@ - @@ -2483,6 +2425,7 @@ + org.apache.maven.plugins maven-antrun-plugin false @@ -2770,7 +2713,7 @@ org.apache.maven.plugins maven-changes-plugin - 2.12.1 + ${maven_changes_version} false @@ -2815,20 +2758,7 @@ maven-project-info-reports-plugin 3.0.0 false - - @@ -2903,22 +2833,23 @@ org.apache.maven.plugins - maven-checkstyle-plugin + maven-antrun-plugin + 1.8 - validate - generate-sources - - - ${maven.multiModuleProjectDirectory}/src/checkstyle/checkstyle_config_nofixmes.xml - UTF-8 - true - true - false - - - check - + delete-module-cache-file + none + + + + + org.apache.maven.plugins + maven-checkstyle-plugin + ${maven_checkstyle_version} + + + hapi-single-module-checkstyle + none @@ -3011,13 +2942,6 @@ integration-testnone - - org.apache.maven.plugins - maven-checkstyle-plugin - - validatenone - - diff --git a/src/checkstyle/checkstyle.xml b/src/checkstyle/checkstyle.xml deleted file mode 100644 index d175e39ca3c..00000000000 --- a/src/checkstyle/checkstyle.xml +++ /dev/null @@ -1,192 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/src/checkstyle/checkstyle_config_nofixmes.xml b/src/checkstyle/checkstyle_config_nofixmes.xml deleted file mode 100644 index 3a6f659b155..00000000000 --- a/src/checkstyle/checkstyle_config_nofixmes.xml +++ /dev/null @@ -1,21 +0,0 @@ - - - - - - - - - - - - - - - - - - - From 148cbf119b3a90d129850ff19fc39ae3fdddc6c0 Mon Sep 17 00:00:00 2001 From: James Agnew Date: Sat, 4 Feb 2023 18:40:39 -0500 Subject: [PATCH 7/9] Clean up references in IPS documents (#4509) * Clean up references in IPS documents * Add changelog --- .../changelog/6_6_0/4509-fix-refs-in-ips.yaml | 6 +++ .../ips/generator/IpsGeneratorSvcImpl.java | 39 +++++++++------ .../jpa/ips/generator/IpsGenerationTest.java | 30 +++++++++-- .../dao/r5/FhirResourceDaoR5ValueSetTest.java | 50 +++++++++++++++++++ .../ResponseHighlighterInterceptor.java | 2 +- 5 files changed, 108 insertions(+), 19 deletions(-) create mode 100644 hapi-fhir-docs/src/main/resources/ca/uhn/hapi/fhir/changelog/6_6_0/4509-fix-refs-in-ips.yaml diff --git a/hapi-fhir-docs/src/main/resources/ca/uhn/hapi/fhir/changelog/6_6_0/4509-fix-refs-in-ips.yaml b/hapi-fhir-docs/src/main/resources/ca/uhn/hapi/fhir/changelog/6_6_0/4509-fix-refs-in-ips.yaml new file mode 100644 index 00000000000..cb5a2892fa8 --- /dev/null +++ b/hapi-fhir-docs/src/main/resources/ca/uhn/hapi/fhir/changelog/6_6_0/4509-fix-refs-in-ips.yaml @@ -0,0 +1,6 @@ +--- +type: fix +issue: 4509 +title: "References to the patient/subject in IPS documents generated using the $summary + operation were not replaced with the bundle-local UUID assigned to the patient. Also, + some dangling references were left in the generated bundle. This has been corrected." diff --git a/hapi-fhir-jpaserver-ips/src/main/java/ca/uhn/fhir/jpa/ips/generator/IpsGeneratorSvcImpl.java b/hapi-fhir-jpaserver-ips/src/main/java/ca/uhn/fhir/jpa/ips/generator/IpsGeneratorSvcImpl.java index b3d51b4b023..62d573b55ea 100644 --- a/hapi-fhir-jpaserver-ips/src/main/java/ca/uhn/fhir/jpa/ips/generator/IpsGeneratorSvcImpl.java +++ b/hapi-fhir-jpaserver-ips/src/main/java/ca/uhn/fhir/jpa/ips/generator/IpsGeneratorSvcImpl.java @@ -114,16 +114,18 @@ public class IpsGeneratorSvcImpl implements IIpsGeneratorSvc { } private IBaseBundle generateIpsForPatient(RequestDetails theRequestDetails, IBaseResource thePatient) { - IIdType originalSubjectId = myFhirContext.getVersion().newIdType().setValue(thePatient.getIdElement().getValue()); + IIdType originalSubjectId = myFhirContext.getVersion().newIdType().setValue(thePatient.getIdElement().getValue()).toUnqualifiedVersionless(); massageResourceId(null, thePatient); IpsContext context = new IpsContext(thePatient, originalSubjectId); + ResourceInclusionCollection globalResourcesToInclude = new ResourceInclusionCollection(); + globalResourcesToInclude.addResourceIfNotAlreadyPresent(thePatient, originalSubjectId.getValue()); + IBaseResource author = myGenerationStrategy.createAuthor(); massageResourceId(context, author); CompositionBuilder compositionBuilder = createComposition(thePatient, context, author); - - ResourceInclusionCollection globalResourcesToInclude = determineInclusions(theRequestDetails, originalSubjectId, context, compositionBuilder); + determineInclusions(theRequestDetails, originalSubjectId, context, compositionBuilder, globalResourcesToInclude); IBaseResource composition = compositionBuilder.getComposition(); @@ -131,10 +133,10 @@ public class IpsGeneratorSvcImpl implements IIpsGeneratorSvc { CustomThymeleafNarrativeGenerator generator = newNarrativeGenerator(globalResourcesToInclude); generator.populateResourceNarrative(myFhirContext, composition); - return createCompositionDocument(thePatient, author, composition, globalResourcesToInclude); + return createCompositionDocument(author, composition, globalResourcesToInclude); } - private IBaseBundle createCompositionDocument(IBaseResource thePatient, IBaseResource author, IBaseResource composition, ResourceInclusionCollection theResourcesToInclude) { + private IBaseBundle createCompositionDocument(IBaseResource author, IBaseResource composition, ResourceInclusionCollection theResourcesToInclude) { BundleBuilder bundleBuilder = new BundleBuilder(myFhirContext); bundleBuilder.setType(Bundle.BundleType.DOCUMENT.toCode()); bundleBuilder.setIdentifier("urn:ietf:rfc:4122", UUID.randomUUID().toString()); @@ -143,9 +145,6 @@ public class IpsGeneratorSvcImpl implements IIpsGeneratorSvc { // Add composition to document bundleBuilder.addDocumentEntry(composition); - // Add subject to document - bundleBuilder.addDocumentEntry(thePatient); - // Add inclusion candidates for (IBaseResource next : theResourcesToInclude.getResources()) { bundleBuilder.addDocumentEntry(next); @@ -158,13 +157,12 @@ public class IpsGeneratorSvcImpl implements IIpsGeneratorSvc { } @Nonnull - private ResourceInclusionCollection determineInclusions(RequestDetails theRequestDetails, IIdType originalSubjectId, IpsContext context, CompositionBuilder theCompositionBuilder) { - ResourceInclusionCollection globalResourcesToInclude = new ResourceInclusionCollection(); + private ResourceInclusionCollection determineInclusions(RequestDetails theRequestDetails, IIdType originalSubjectId, IpsContext context, CompositionBuilder theCompositionBuilder, ResourceInclusionCollection theGlobalResourcesToInclude) { SectionRegistry sectionRegistry = myGenerationStrategy.getSectionRegistry(); for (SectionRegistry.Section nextSection : sectionRegistry.getSections()) { - determineInclusionsForSection(theRequestDetails, originalSubjectId, context, theCompositionBuilder, globalResourcesToInclude, nextSection); + determineInclusionsForSection(theRequestDetails, originalSubjectId, context, theCompositionBuilder, theGlobalResourcesToInclude, nextSection); } - return globalResourcesToInclude; + return theGlobalResourcesToInclude; } private void determineInclusionsForSection(RequestDetails theRequestDetails, IIdType theOriginalSubjectId, IpsContext theIpsContext, CompositionBuilder theCompositionBuilder, ResourceInclusionCollection theGlobalResourcesToInclude, SectionRegistry.Section theSection) { @@ -241,8 +239,15 @@ public class IpsGeneratorSvcImpl implements IIpsGeneratorSvc { if (isNotBlank(existingReference)) { existingReference = new IdType(existingReference).toUnqualifiedVersionless().getValue(); String replacement = theGlobalResourcesToInclude.getIdSubstitution(existingReference); - if (isNotBlank(replacement) && !replacement.equals(existingReference)) { - nextReference.getResourceReference().setReference(replacement); + if (isNotBlank(replacement)) { + if (!replacement.equals(existingReference)) { + nextReference.getResourceReference().setReference(replacement); + } + } else if (theGlobalResourcesToInclude.getResourceById(existingReference) == null) { + // If this reference doesn't point to something we have actually + // included in the bundle, clear the reference. + nextReference.getResourceReference().setReference(null); + nextReference.getResourceReference().setResource(null); } } } @@ -541,7 +546,11 @@ public class IpsGeneratorSvcImpl implements IIpsGeneratorSvc { } public IBaseResource getResourceById(IIdType theReference) { - return myIdToResource.get(theReference.toUnqualifiedVersionless().getValue()); + return getResourceById(theReference.toUnqualifiedVersionless().getValue()); + } + + public IBaseResource getResourceById(String theReference) { + return myIdToResource.get(theReference); } @Nullable diff --git a/hapi-fhir-jpaserver-ips/src/test/java/ca/uhn/fhir/jpa/ips/generator/IpsGenerationTest.java b/hapi-fhir-jpaserver-ips/src/test/java/ca/uhn/fhir/jpa/ips/generator/IpsGenerationTest.java index 5de2d5517fd..eb140fa1881 100644 --- a/hapi-fhir-jpaserver-ips/src/test/java/ca/uhn/fhir/jpa/ips/generator/IpsGenerationTest.java +++ b/hapi-fhir-jpaserver-ips/src/test/java/ca/uhn/fhir/jpa/ips/generator/IpsGenerationTest.java @@ -1,5 +1,6 @@ package ca.uhn.fhir.jpa.ips.generator; +import ca.uhn.fhir.batch2.jobs.models.BatchResourceId; import ca.uhn.fhir.context.FhirContext; import ca.uhn.fhir.jpa.api.dao.DaoRegistry; import ca.uhn.fhir.jpa.ips.api.IIpsGenerationStrategy; @@ -8,8 +9,11 @@ import ca.uhn.fhir.jpa.ips.strategy.DefaultIpsGenerationStrategy; import ca.uhn.fhir.jpa.model.util.JpaConstants; import ca.uhn.fhir.jpa.provider.BaseResourceProviderR4Test; import ca.uhn.fhir.util.ClasspathUtil; +import org.hl7.fhir.instance.model.api.IBaseResource; import org.hl7.fhir.r4.model.Bundle; +import org.hl7.fhir.r4.model.MedicationStatement; import org.hl7.fhir.r4.model.Parameters; +import org.hl7.fhir.r4.model.Patient; import org.junit.jupiter.api.AfterEach; import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; @@ -18,7 +22,10 @@ import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.springframework.test.context.ContextConfiguration; +import static org.hamcrest.MatcherAssert.assertThat; +import static org.hamcrest.Matchers.matchesPattern; import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertNull; @ContextConfiguration(classes = {IpsGenerationTest.IpsConfig.class}) public class IpsGenerationTest extends BaseResourceProviderR4Test { @@ -28,12 +35,12 @@ public class IpsGenerationTest extends BaseResourceProviderR4Test { @BeforeEach public void beforeEach() { - myServer.withServer(t->t.registerProvider(myIpsOperationProvider)); + myServer.withServer(t -> t.registerProvider(myIpsOperationProvider)); } @AfterEach public void afterEach() { - myServer.withServer(t->t.unregisterProvider(myIpsOperationProvider)); + myServer.withServer(t -> t.unregisterProvider(myIpsOperationProvider)); } @@ -55,10 +62,27 @@ public class IpsGenerationTest extends BaseResourceProviderR4Test { .withNoParameters(Parameters.class) .returnResourceType(Bundle.class) .execute(); - ourLog.info("Output: {}", myFhirContext.newJsonParser().setPrettyPrint(true).encodeResourceToString(output)); + // Verify + assertEquals(37, output.getEntry().size()); + String patientId = findFirstEntryResource(output, Patient.class).getId(); + assertThat(patientId, matchesPattern("urn:uuid:.*")); + MedicationStatement medicationStatement = findFirstEntryResource(output, MedicationStatement.class); + assertEquals(patientId, medicationStatement.getSubject().getReference()); + assertNull(medicationStatement.getInformationSource().getReference()); + } + + @SuppressWarnings("unchecked") + private T findFirstEntryResource(Bundle theBundle, Class theType) { + return (T) theBundle + .getEntry() + .stream() + .filter(t -> theType.isAssignableFrom(t.getResource().getClass())) + .findFirst() + .orElseThrow() + .getResource(); } diff --git a/hapi-fhir-jpaserver-test-r5/src/test/java/ca/uhn/fhir/jpa/dao/r5/FhirResourceDaoR5ValueSetTest.java b/hapi-fhir-jpaserver-test-r5/src/test/java/ca/uhn/fhir/jpa/dao/r5/FhirResourceDaoR5ValueSetTest.java index 9fb6b1d0a0a..77d4b524afb 100644 --- a/hapi-fhir-jpaserver-test-r5/src/test/java/ca/uhn/fhir/jpa/dao/r5/FhirResourceDaoR5ValueSetTest.java +++ b/hapi-fhir-jpaserver-test-r5/src/test/java/ca/uhn/fhir/jpa/dao/r5/FhirResourceDaoR5ValueSetTest.java @@ -7,11 +7,14 @@ import ca.uhn.fhir.context.support.ValidationSupportContext; import ca.uhn.fhir.context.support.ValueSetExpansionOptions; import ca.uhn.fhir.i18n.Msg; import ca.uhn.fhir.jpa.api.config.DaoConfig; +import ca.uhn.fhir.jpa.api.model.ExpungeOptions; +import ca.uhn.fhir.jpa.model.entity.ResourceTable; import ca.uhn.fhir.jpa.term.api.ITermDeferredStorageSvc; import ca.uhn.fhir.jpa.term.custom.CustomTerminologySet; import ca.uhn.fhir.jpa.util.ValueSetTestUtil; import ca.uhn.fhir.rest.server.exceptions.InternalErrorException; import ca.uhn.fhir.rest.server.exceptions.InvalidRequestException; +import ca.uhn.fhir.rest.server.exceptions.ResourceGoneException; import org.hl7.fhir.common.hapi.validation.support.CachingValidationSupport; import org.hl7.fhir.instance.model.api.IIdType; import org.hl7.fhir.instance.model.api.IPrimitiveType; @@ -19,6 +22,7 @@ import org.hl7.fhir.r5.model.CodeSystem; import org.hl7.fhir.r5.model.CodeType; import org.hl7.fhir.r5.model.CodeableConcept; import org.hl7.fhir.r5.model.Coding; +import org.hl7.fhir.r5.model.Enumerations; import org.hl7.fhir.r5.model.IdType; import org.hl7.fhir.r5.model.StringType; import org.hl7.fhir.r5.model.UriType; @@ -30,6 +34,7 @@ import org.springframework.beans.factory.annotation.Autowired; import org.springframework.transaction.annotation.Transactional; import java.io.IOException; +import java.util.Optional; import static org.hamcrest.MatcherAssert.assertThat; import static org.hamcrest.Matchers.containsString; @@ -38,6 +43,7 @@ import static org.hamcrest.Matchers.stringContainsInOrder; import static org.junit.jupiter.api.Assertions.assertEquals; import static org.junit.jupiter.api.Assertions.assertFalse; import static org.junit.jupiter.api.Assertions.assertNotNull; +import static org.junit.jupiter.api.Assertions.assertThrows; import static org.junit.jupiter.api.Assertions.assertTrue; import static org.junit.jupiter.api.Assertions.fail; @@ -56,6 +62,7 @@ public class FhirResourceDaoR5ValueSetTest extends BaseJpaR5Test { public void after() { myDaoConfig.setPreExpandValueSets(new DaoConfig().isPreExpandValueSets()); myDaoConfig.setMaximumExpansionSize(new DaoConfig().getMaximumExpansionSize()); + myDaoConfig.setExpungeEnabled(new DaoConfig().isExpungeEnabled()); } @@ -248,6 +255,49 @@ public class FhirResourceDaoR5ValueSetTest extends BaseJpaR5Test { } + + /** + * See #4305 + */ + @Test + public void testDeleteExpungePreExpandedValueSet() { + myDaoConfig.setExpungeEnabled(true); + + // Create valueset + ValueSet vs = myValidationSupport.fetchResource(ValueSet.class, "http://hl7.org/fhir/ValueSet/address-use"); + assertNotNull(vs); + IIdType id = myValueSetDao.create(vs).getId().toUnqualifiedVersionless(); + + // Update valueset + vs.setName("Hello"); + assertEquals("2", myValueSetDao.update(vs, mySrd).getId().getVersionIdPart()); + runInTransaction(()->{ + Optional resource = myResourceTableDao.findById(id.getIdPartAsLong()); + assertTrue(resource.isPresent()); + }); + + // Precalculate + myTerminologyDeferredStorageSvc.saveAllDeferred(); + myTermSvc.preExpandDeferredValueSetsToTerminologyTables(); + logAllValueSets(); + + // Delete + myValueSetDao.delete(id, mySrd); + + // Verify it's deleted + assertThrows(ResourceGoneException.class, ()-> myValueSetDao.read(id, mySrd)); + + // Expunge + myValueSetDao.expunge(id, new ExpungeOptions().setExpungeDeletedResources(true).setExpungeOldVersions(true), mySrd); + + // Verify expunged + runInTransaction(()->{ + Optional resource = myResourceTableDao.findById(id.getIdPartAsLong()); + assertFalse(resource.isPresent()); + }); + } + + @Test public void testExpandByValueSet_ExceedsMaxSize() { // Add a bunch of codes diff --git a/hapi-fhir-server/src/main/java/ca/uhn/fhir/rest/server/interceptor/ResponseHighlighterInterceptor.java b/hapi-fhir-server/src/main/java/ca/uhn/fhir/rest/server/interceptor/ResponseHighlighterInterceptor.java index ea10c3f73e8..1fcd7d7858d 100644 --- a/hapi-fhir-server/src/main/java/ca/uhn/fhir/rest/server/interceptor/ResponseHighlighterInterceptor.java +++ b/hapi-fhir-server/src/main/java/ca/uhn/fhir/rest/server/interceptor/ResponseHighlighterInterceptor.java @@ -814,7 +814,7 @@ public class ResponseHighlighterInterceptor { writeLength(theServletResponse, outputBuffer.length()); theServletResponse.getWriter().append(" total including HTML)"); - theServletResponse.getWriter().append(" in estimated "); + theServletResponse.getWriter().append(" in approximately "); theServletResponse.getWriter().append(writeSw.toString()); theServletResponse.getWriter().append(""); From 26a700927722b4e78d98ff86312f726398f7fb94 Mon Sep 17 00:00:00 2001 From: michaelabuckley Date: Wed, 8 Feb 2023 17:50:46 -0500 Subject: [PATCH 8/9] Change CLOB columns oid in Postgres (#4528) * Change CLOB columns to generate oid in Postgres to match the dumb Hibernate driver bug. Fix three columns --- .../hapi/fhir/changelog/6_4_0/4528-oid-for-text.yaml | 7 +++++++ .../jpa/migrate/tasks/HapiFhirJpaMigrationTasks.java | 12 ++++++++++++ .../taskdef/ColumnTypeToDriverTypeToSqlType.java | 2 +- 3 files changed, 20 insertions(+), 1 deletion(-) create mode 100644 hapi-fhir-docs/src/main/resources/ca/uhn/hapi/fhir/changelog/6_4_0/4528-oid-for-text.yaml diff --git a/hapi-fhir-docs/src/main/resources/ca/uhn/hapi/fhir/changelog/6_4_0/4528-oid-for-text.yaml b/hapi-fhir-docs/src/main/resources/ca/uhn/hapi/fhir/changelog/6_4_0/4528-oid-for-text.yaml new file mode 100644 index 00000000000..5fcc0981953 --- /dev/null +++ b/hapi-fhir-docs/src/main/resources/ca/uhn/hapi/fhir/changelog/6_4_0/4528-oid-for-text.yaml @@ -0,0 +1,7 @@ +--- +type: fix +issue: 4528 +title: "Three database columns have been changed from type TEXT to type OID + when running in Postgres: + BT2_JOB_INSTANCE.PARAMS_JSON_LOB, BT2_JOB_INSTANCE.REPORT, and BT2_WORK_CHUNK.CHUNK_DATA. + This prevents VACUUM erasing binary objects that are still in use." diff --git a/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/migrate/tasks/HapiFhirJpaMigrationTasks.java b/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/migrate/tasks/HapiFhirJpaMigrationTasks.java index c6335beccc0..a19232bfa0c 100644 --- a/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/migrate/tasks/HapiFhirJpaMigrationTasks.java +++ b/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/migrate/tasks/HapiFhirJpaMigrationTasks.java @@ -108,6 +108,18 @@ public class HapiFhirJpaMigrationTasks extends BaseMigrationTasks { .online(true) .withColumns("SEARCH_PID") .onlyAppliesToPlatforms(NON_AUTOMATIC_FK_INDEX_PLATFORMS); + + // fix Postgres clob types - that stupid oid driver problem is still there + // BT2_JOB_INSTANCE.PARAMS_JSON_LOB + version.onTable("BT2_JOB_INSTANCE") + .migratePostgresTextClobToBinaryClob("20230208.1", "PARAMS_JSON_LOB"); + // BT2_JOB_INSTANCE.REPORT + version.onTable("BT2_JOB_INSTANCE") + .migratePostgresTextClobToBinaryClob("20230208.2", "REPORT"); + // BT2_WORK_CHUNK.CHUNK_DATA + version.onTable("BT2_WORK_CHUNK") + .migratePostgresTextClobToBinaryClob("20230208.3", "CHUNK_DATA"); + } private void init620() { diff --git a/hapi-fhir-sql-migrate/src/main/java/ca/uhn/fhir/jpa/migrate/taskdef/ColumnTypeToDriverTypeToSqlType.java b/hapi-fhir-sql-migrate/src/main/java/ca/uhn/fhir/jpa/migrate/taskdef/ColumnTypeToDriverTypeToSqlType.java index 15eeb8efa28..0aa498f9f02 100644 --- a/hapi-fhir-sql-migrate/src/main/java/ca/uhn/fhir/jpa/migrate/taskdef/ColumnTypeToDriverTypeToSqlType.java +++ b/hapi-fhir-sql-migrate/src/main/java/ca/uhn/fhir/jpa/migrate/taskdef/ColumnTypeToDriverTypeToSqlType.java @@ -109,7 +109,7 @@ public final class ColumnTypeToDriverTypeToSqlType { setColumnType(ColumnTypeEnum.CLOB, DriverTypeEnum.MARIADB_10_1, "longtext"); setColumnType(ColumnTypeEnum.CLOB, DriverTypeEnum.MYSQL_5_7, "longtext"); setColumnType(ColumnTypeEnum.CLOB, DriverTypeEnum.ORACLE_12C, "clob"); - setColumnType(ColumnTypeEnum.CLOB, DriverTypeEnum.POSTGRES_9_4, "text"); + setColumnType(ColumnTypeEnum.CLOB, DriverTypeEnum.POSTGRES_9_4, "oid"); // the PG driver will write oid into a `text` column setColumnType(ColumnTypeEnum.CLOB, DriverTypeEnum.MSSQL_2012, "varchar(MAX)"); } From 765fedfefab9a9e37d57935ae29278a772214025 Mon Sep 17 00:00:00 2001 From: James Agnew Date: Thu, 9 Feb 2023 09:35:33 -0500 Subject: [PATCH 9/9] Additional tweaks for #4509 (#4510) * Additional tweaks for #4509 * More teaks * format imports --- .../ips/generator/IpsGeneratorSvcImpl.java | 85 +++++++---- .../jpa/ips/generator/IpsGenerationTest.java | 79 +++++++++-- .../generator/IpsGeneratorSvcImplTest.java | 132 +++++++++++++----- .../resources/tiny-patient-everything.json.gz | Bin 0 -> 1796 bytes hapi-fhir-jpaserver-uhnfhirtest/pom.xml | 17 ++- .../ca/uhn/fhirtest/TestRestfulServer.java | 2 + .../ca/uhn/fhirtest/config/TestR4Config.java | 20 +++ 7 files changed, 254 insertions(+), 81 deletions(-) create mode 100644 hapi-fhir-jpaserver-ips/src/test/resources/tiny-patient-everything.json.gz diff --git a/hapi-fhir-jpaserver-ips/src/main/java/ca/uhn/fhir/jpa/ips/generator/IpsGeneratorSvcImpl.java b/hapi-fhir-jpaserver-ips/src/main/java/ca/uhn/fhir/jpa/ips/generator/IpsGeneratorSvcImpl.java index 62d573b55ea..e85d1241b28 100644 --- a/hapi-fhir-jpaserver-ips/src/main/java/ca/uhn/fhir/jpa/ips/generator/IpsGeneratorSvcImpl.java +++ b/hapi-fhir-jpaserver-ips/src/main/java/ca/uhn/fhir/jpa/ips/generator/IpsGeneratorSvcImpl.java @@ -22,6 +22,7 @@ package ca.uhn.fhir.jpa.ips.generator; import ca.uhn.fhir.context.FhirContext; import ca.uhn.fhir.context.RuntimeResourceDefinition; +import ca.uhn.fhir.context.RuntimeSearchParam; import ca.uhn.fhir.fhirpath.IFhirPathEvaluationContext; import ca.uhn.fhir.jpa.api.dao.DaoRegistry; import ca.uhn.fhir.jpa.api.dao.IFhirResourceDao; @@ -32,6 +33,7 @@ import ca.uhn.fhir.jpa.ips.api.SectionRegistry; import ca.uhn.fhir.jpa.searchparam.SearchParameterMap; import ca.uhn.fhir.model.api.Include; import ca.uhn.fhir.model.api.ResourceMetadataKeyEnum; +import ca.uhn.fhir.model.dstu2.resource.Observation; import ca.uhn.fhir.model.valueset.BundleEntrySearchModeEnum; import ca.uhn.fhir.narrative.CustomThymeleafNarrativeGenerator; import ca.uhn.fhir.rest.api.server.IBundleProvider; @@ -42,6 +44,10 @@ import ca.uhn.fhir.util.BundleBuilder; import ca.uhn.fhir.util.CompositionBuilder; import ca.uhn.fhir.util.ResourceReferenceInfo; import ca.uhn.fhir.util.ValidateUtil; +import com.google.common.collect.BiMap; +import com.google.common.collect.HashBiMap; +import org.apache.commons.collections4.BidiMap; +import org.apache.commons.collections4.bidimap.DualHashBidiMap; import org.hl7.fhir.instance.model.api.IBase; import org.hl7.fhir.instance.model.api.IBaseBundle; import org.hl7.fhir.instance.model.api.IBaseExtension; @@ -66,6 +72,7 @@ import java.util.List; import java.util.Map; import java.util.Set; import java.util.UUID; +import java.util.stream.Collectors; import static ca.uhn.fhir.jpa.term.api.ITermLoaderSvc.LOINC_URI; import static org.apache.commons.lang3.StringUtils.isNotBlank; @@ -214,6 +221,8 @@ public class IpsGeneratorSvcImpl implements IIpsGeneratorSvc { nextCandidate = previouslyExistingResource; sectionResourcesToInclude.addResourceIfNotAlreadyPresent(nextCandidate, originalResourceId); + } else if (theGlobalResourcesToInclude.hasResourceWithReplacementId(originalResourceId)) { + sectionResourcesToInclude.addResourceIfNotAlreadyPresent(nextCandidate, originalResourceId); } else { IIdType id = myGenerationStrategy.massageResourceId(theIpsContext, nextCandidate); nextCandidate.setId(id); @@ -226,33 +235,6 @@ public class IpsGeneratorSvcImpl implements IIpsGeneratorSvc { } - /* - * Update any references within the added candidates - This is important - * because we might be replacing resource IDs before including them in - * the summary, so we need to also update the references to those - * resources. - */ - for (IBaseResource nextResource : sectionResourcesToInclude.getResources()) { - List references = myFhirContext.newTerser().getAllResourceReferences(nextResource); - for (ResourceReferenceInfo nextReference : references) { - String existingReference = nextReference.getResourceReference().getReferenceElement().getValue(); - if (isNotBlank(existingReference)) { - existingReference = new IdType(existingReference).toUnqualifiedVersionless().getValue(); - String replacement = theGlobalResourcesToInclude.getIdSubstitution(existingReference); - if (isNotBlank(replacement)) { - if (!replacement.equals(existingReference)) { - nextReference.getResourceReference().setReference(replacement); - } - } else if (theGlobalResourcesToInclude.getResourceById(existingReference) == null) { - // If this reference doesn't point to something we have actually - // included in the bundle, clear the reference. - nextReference.getResourceReference().setReference(null); - nextReference.getResourceReference().setResource(null); - } - } - } - } - } if (sectionResourcesToInclude.isEmpty() && theSection.getNoInfoGenerator() != null) { @@ -266,6 +248,33 @@ public class IpsGeneratorSvcImpl implements IIpsGeneratorSvc { sectionResourcesToInclude.addResourceIfNotAlreadyPresent(noInfoResource, id); } + /* + * Update any references within the added candidates - This is important + * because we might be replacing resource IDs before including them in + * the summary, so we need to also update the references to those + * resources. + */ + for (IBaseResource nextResource : sectionResourcesToInclude.getResources()) { + List references = myFhirContext.newTerser().getAllResourceReferences(nextResource); + for (ResourceReferenceInfo nextReference : references) { + String existingReference = nextReference.getResourceReference().getReferenceElement().getValue(); + if (isNotBlank(existingReference)) { + existingReference = new IdType(existingReference).toUnqualifiedVersionless().getValue(); + String replacement = theGlobalResourcesToInclude.getIdSubstitution(existingReference); + if (isNotBlank(replacement)) { + if (!replacement.equals(existingReference)) { + nextReference.getResourceReference().setReference(replacement); + } + } else if (theGlobalResourcesToInclude.getResourceById(existingReference) == null) { + // If this reference doesn't point to something we have actually + // included in the bundle, clear the reference. + nextReference.getResourceReference().setReference(null); + nextReference.getResourceReference().setResource(null); + } + } + } + } + addSection(theSection, theCompositionBuilder, sectionResourcesToInclude, theGlobalResourcesToInclude); } @@ -278,6 +287,9 @@ public class IpsGeneratorSvcImpl implements IIpsGeneratorSvc { sectionBuilder.addCodeCoding(LOINC_URI, theSection.getSectionCode(), theSection.getSectionDisplay()); for (IBaseResource next : theResourcesToInclude.getResources()) { + if (ResourceMetadataKeyEnum.ENTRY_SEARCH_MODE.get(next) == BundleEntrySearchModeEnum.INCLUDE) { + continue; + } IBaseExtension narrativeLink = ((IBaseHasExtensions) next).addExtension(); narrativeLink.setUrl("http://hl7.org/fhir/StructureDefinition/narrativeLink"); @@ -314,7 +326,18 @@ public class IpsGeneratorSvcImpl implements IIpsGeneratorSvc { private String determinePatientCompartmentSearchParameterName(String theResourceType) { RuntimeResourceDefinition resourceDef = myFhirContext.getResourceDefinition(theResourceType); - return resourceDef.getSearchParamsForCompartmentName("Patient").get(0).getName(); + Set searchParams = resourceDef.getSearchParamsForCompartmentName("Patient") + .stream() + .map(RuntimeSearchParam::getName) + .collect(Collectors.toSet()); + // Prefer "patient", then "subject" then anything else + if (searchParams.contains(Observation.SP_PATIENT)) { + return Observation.SP_PATIENT; + } + if (searchParams.contains(Observation.SP_SUBJECT)) { + return Observation.SP_SUBJECT; + } + return searchParams.iterator().next(); } private void massageResourceId(IpsContext theIpsContext, IBaseResource theResource) { @@ -519,7 +542,7 @@ public class IpsGeneratorSvcImpl implements IIpsGeneratorSvc { private final List myResources = new ArrayList<>(); private final Map myIdToResource = new HashMap<>(); - private final Map myOriginalIdToNewId = new HashMap<>(); + private final BiMap myOriginalIdToNewId = HashBiMap.create(); public List getResources() { return myResources; @@ -549,6 +572,10 @@ public class IpsGeneratorSvcImpl implements IIpsGeneratorSvc { return getResourceById(theReference.toUnqualifiedVersionless().getValue()); } + public boolean hasResourceWithReplacementId(String theReplacementId) { + return myOriginalIdToNewId.containsValue(theReplacementId); + } + public IBaseResource getResourceById(String theReference) { return myIdToResource.get(theReference); } diff --git a/hapi-fhir-jpaserver-ips/src/test/java/ca/uhn/fhir/jpa/ips/generator/IpsGenerationTest.java b/hapi-fhir-jpaserver-ips/src/test/java/ca/uhn/fhir/jpa/ips/generator/IpsGenerationTest.java index eb140fa1881..f8d7d76ec1b 100644 --- a/hapi-fhir-jpaserver-ips/src/test/java/ca/uhn/fhir/jpa/ips/generator/IpsGenerationTest.java +++ b/hapi-fhir-jpaserver-ips/src/test/java/ca/uhn/fhir/jpa/ips/generator/IpsGenerationTest.java @@ -1,7 +1,7 @@ package ca.uhn.fhir.jpa.ips.generator; -import ca.uhn.fhir.batch2.jobs.models.BatchResourceId; import ca.uhn.fhir.context.FhirContext; +import ca.uhn.fhir.jpa.api.config.DaoConfig; import ca.uhn.fhir.jpa.api.dao.DaoRegistry; import ca.uhn.fhir.jpa.ips.api.IIpsGenerationStrategy; import ca.uhn.fhir.jpa.ips.provider.IpsOperationProvider; @@ -9,11 +9,16 @@ import ca.uhn.fhir.jpa.ips.strategy.DefaultIpsGenerationStrategy; import ca.uhn.fhir.jpa.model.util.JpaConstants; import ca.uhn.fhir.jpa.provider.BaseResourceProviderR4Test; import ca.uhn.fhir.util.ClasspathUtil; +import ca.uhn.fhir.validation.FhirValidator; +import ca.uhn.fhir.validation.ValidationResult; +import org.hl7.fhir.common.hapi.validation.validator.FhirInstanceValidator; import org.hl7.fhir.instance.model.api.IBaseResource; import org.hl7.fhir.r4.model.Bundle; +import org.hl7.fhir.r4.model.Condition; import org.hl7.fhir.r4.model.MedicationStatement; import org.hl7.fhir.r4.model.Parameters; import org.hl7.fhir.r4.model.Patient; +import org.hl7.fhir.r4.model.Resource; import org.junit.jupiter.api.AfterEach; import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; @@ -22,10 +27,13 @@ import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.springframework.test.context.ContextConfiguration; +import java.util.List; + import static org.hamcrest.MatcherAssert.assertThat; import static org.hamcrest.Matchers.matchesPattern; import static org.junit.jupiter.api.Assertions.assertEquals; import static org.junit.jupiter.api.Assertions.assertNull; +import static org.junit.jupiter.api.Assertions.assertTrue; @ContextConfiguration(classes = {IpsGenerationTest.IpsConfig.class}) public class IpsGenerationTest extends BaseResourceProviderR4Test { @@ -41,6 +49,7 @@ public class IpsGenerationTest extends BaseResourceProviderR4Test { @AfterEach public void afterEach() { myServer.withServer(t -> t.unregisterProvider(myIpsOperationProvider)); + myDaoConfig.setResourceClientIdStrategy(DaoConfig.ClientIdStrategyEnum.ALPHANUMERIC); } @@ -65,26 +74,52 @@ public class IpsGenerationTest extends BaseResourceProviderR4Test { ourLog.info("Output: {}", myFhirContext.newJsonParser().setPrettyPrint(true).encodeResourceToString(output)); // Verify - - assertEquals(37, output.getEntry().size()); - String patientId = findFirstEntryResource(output, Patient.class).getId(); + validateDocument(outcome); + assertEquals(117, output.getEntry().size()); + String patientId = findFirstEntryResource(output, Patient.class, 1).getId(); assertThat(patientId, matchesPattern("urn:uuid:.*")); - MedicationStatement medicationStatement = findFirstEntryResource(output, MedicationStatement.class); + MedicationStatement medicationStatement = findFirstEntryResource(output, MedicationStatement.class, 2); assertEquals(patientId, medicationStatement.getSubject().getReference()); assertNull(medicationStatement.getInformationSource().getReference()); } - @SuppressWarnings("unchecked") - private T findFirstEntryResource(Bundle theBundle, Class theType) { - return (T) theBundle - .getEntry() - .stream() - .filter(t -> theType.isAssignableFrom(t.getResource().getClass())) - .findFirst() - .orElseThrow() - .getResource(); + @Test + public void testGenerateTinyPatientSummary() { + myDaoConfig.setResourceClientIdStrategy(DaoConfig.ClientIdStrategyEnum.ANY); + + Bundle sourceData = ClasspathUtil.loadCompressedResource(myFhirContext, Bundle.class, "/tiny-patient-everything.json.gz"); + sourceData.setType(Bundle.BundleType.TRANSACTION); + for (Bundle.BundleEntryComponent nextEntry : sourceData.getEntry()) { + nextEntry.getRequest().setMethod(Bundle.HTTPVerb.PUT); + nextEntry.getRequest().setUrl(nextEntry.getResource().getIdElement().toUnqualifiedVersionless().getValue()); + } + Bundle outcome = mySystemDao.transaction(mySrd, sourceData); + ourLog.info("Created {} resources", outcome.getEntry().size()); + + Bundle output = myClient + .operation() + .onInstance("Patient/5342998") + .named(JpaConstants.OPERATION_SUMMARY) + .withNoParameters(Parameters.class) + .returnResourceType(Bundle.class) + .execute(); + ourLog.info("Output: {}", myFhirContext.newJsonParser().setPrettyPrint(true).encodeResourceToString(output)); + + // Verify + validateDocument(outcome); + assertEquals(7, output.getEntry().size()); + String patientId = findFirstEntryResource(output, Patient.class, 1).getId(); + assertThat(patientId, matchesPattern("urn:uuid:.*")); + assertEquals(patientId, findEntryResource(output, Condition.class, 0, 2).getSubject().getReference()); + assertEquals(patientId, findEntryResource(output, Condition.class, 1, 2).getSubject().getReference()); } + private void validateDocument(Bundle theOutcome) { + FhirValidator validator = myFhirContext.newValidator(); + validator.registerValidatorModule(new FhirInstanceValidator(myFhirContext)); + ValidationResult validation = validator.validateWithResult(theOutcome); + assertTrue(validation.isSuccessful(), () -> myFhirContext.newJsonParser().setPrettyPrint(true).encodeResourceToString(validation.toOperationOutcome())); + } @Configuration public static class IpsConfig { @@ -107,5 +142,21 @@ public class IpsGenerationTest extends BaseResourceProviderR4Test { } + @SuppressWarnings("unchecked") + private static T findFirstEntryResource(Bundle theBundle, Class theType, int theExpectedCount) { + return findEntryResource(theBundle, theType, 0, theExpectedCount); + } + + @SuppressWarnings("unchecked") + static T findEntryResource(Bundle theBundle, Class theType, int index, int theExpectedCount) { + List resources = theBundle + .getEntry() + .stream() + .map(Bundle.BundleEntryComponent::getResource) + .filter(r -> theType.isAssignableFrom(r.getClass())) + .toList(); + assertEquals(theExpectedCount, resources.size()); + return (T) resources.get(index); + } } diff --git a/hapi-fhir-jpaserver-ips/src/test/java/ca/uhn/fhir/jpa/ips/generator/IpsGeneratorSvcImplTest.java b/hapi-fhir-jpaserver-ips/src/test/java/ca/uhn/fhir/jpa/ips/generator/IpsGeneratorSvcImplTest.java index 12ef04f993d..efafd666eb6 100644 --- a/hapi-fhir-jpaserver-ips/src/test/java/ca/uhn/fhir/jpa/ips/generator/IpsGeneratorSvcImplTest.java +++ b/hapi-fhir-jpaserver-ips/src/test/java/ca/uhn/fhir/jpa/ips/generator/IpsGeneratorSvcImplTest.java @@ -33,6 +33,7 @@ import org.hl7.fhir.r4.model.DateTimeType; import org.hl7.fhir.r4.model.Device; import org.hl7.fhir.r4.model.DeviceUseStatement; import org.hl7.fhir.r4.model.DiagnosticReport; +import org.hl7.fhir.r4.model.Encounter; import org.hl7.fhir.r4.model.IdType; import org.hl7.fhir.r4.model.Immunization; import org.hl7.fhir.r4.model.Medication; @@ -60,12 +61,15 @@ import java.util.Collections; import java.util.List; import java.util.stream.Collectors; +import static ca.uhn.fhir.jpa.ips.generator.IpsGenerationTest.findEntryResource; import static org.hamcrest.MatcherAssert.assertThat; import static org.hamcrest.Matchers.containsString; import static org.hamcrest.Matchers.startsWith; import static org.junit.jupiter.api.Assertions.assertEquals; import static org.mockito.ArgumentMatchers.any; import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.times; +import static org.mockito.Mockito.verify; import static org.mockito.Mockito.when; @ExtendWith(MockitoExtension.class) @@ -74,6 +78,8 @@ public class IpsGeneratorSvcImplTest { public static final String MEDICATION_ID = "Medication/tyl"; public static final String MEDICATION_STATEMENT_ID = "MedicationStatement/meds"; public static final String MEDICATION_STATEMENT_ID2 = "MedicationStatement/meds2"; + public static final String PATIENT_ID = "Patient/123"; + public static final String ENCOUNTER_ID = "Encounter/encounter"; private static final List> RESOURCE_TYPES = Lists.newArrayList( AllergyIntolerance.class, CarePlan.class, @@ -157,7 +163,7 @@ public class IpsGeneratorSvcImplTest { registerRemainingResourceDaos(); // Test - Bundle outcome = (Bundle) mySvc.generateIps(new SystemRequestDetails(), new IdType("Patient/123")); + Bundle outcome = (Bundle) mySvc.generateIps(new SystemRequestDetails(), new IdType(PATIENT_ID)); // Verify Bundle Contents List contentResourceTypes = toEntryResourceTypeStrings(outcome); @@ -170,12 +176,7 @@ public class IpsGeneratorSvcImplTest { // Verify Composition compositions = (Composition) outcome.getEntry().get(0).getResource(); - Composition.SectionComponent section = compositions - .getSection() - .stream() - .filter(t -> t.getTitle().equals(myStrategy.getSectionRegistry().getSection(IpsSectionEnum.MEDICATION_SUMMARY).getTitle())) - .findFirst() - .orElseThrow(); + Composition.SectionComponent section = findSection(compositions, IpsSectionEnum.MEDICATION_SUMMARY); HtmlPage narrativeHtml = HtmlUtil.parseAsHtml(section.getText().getDivAsString()); ourLog.info("Narrative:\n{}", narrativeHtml.asXml()); @@ -191,6 +192,17 @@ public class IpsGeneratorSvcImplTest { assertThat(row.getCell(4).asNormalizedText(), containsString("2023")); } + @Nonnull + private Composition.SectionComponent findSection(Composition compositions, IpsSectionEnum sectionEnum) { + Composition.SectionComponent section = compositions + .getSection() + .stream() + .filter(t -> t.getTitle().equals(myStrategy.getSectionRegistry().getSection(sectionEnum).getTitle())) + .findFirst() + .orElseThrow(); + return section; + } + @Test public void testMedicationSummary_DuplicateSecondaryResources() { myStrategy.setSectionRegistry(new SectionRegistry().addGlobalCustomizer(t -> t.withNoInfoGenerator(null))); @@ -209,7 +221,7 @@ public class IpsGeneratorSvcImplTest { registerRemainingResourceDaos(); // Test - Bundle outcome = (Bundle) mySvc.generateIps(new SystemRequestDetails(), new IdType("Patient/123")); + Bundle outcome = (Bundle) mySvc.generateIps(new SystemRequestDetails(), new IdType(PATIENT_ID)); // Verify Bundle Contents List contentResourceTypes = toEntryResourceTypeStrings(outcome); @@ -248,7 +260,7 @@ public class IpsGeneratorSvcImplTest { registerRemainingResourceDaos(); // Test - Bundle outcome = (Bundle) mySvc.generateIps(new SystemRequestDetails(), new IdType("Patient/123")); + Bundle outcome = (Bundle) mySvc.generateIps(new SystemRequestDetails(), new IdType(PATIENT_ID)); // Verify Bundle Contents List contentResourceTypes = toEntryResourceTypeStrings(outcome); @@ -263,12 +275,7 @@ public class IpsGeneratorSvcImplTest { // Verify narrative - should have 2 rows (one for each primary MedicationStatement) Composition compositions = (Composition) outcome.getEntry().get(0).getResource(); - Composition.SectionComponent section = compositions - .getSection() - .stream() - .filter(t -> t.getTitle().equals(myStrategy.getSectionRegistry().getSection(IpsSectionEnum.MEDICATION_SUMMARY).getTitle())) - .findFirst() - .orElseThrow(); + Composition.SectionComponent section = findSection(compositions, IpsSectionEnum.MEDICATION_SUMMARY); HtmlPage narrativeHtml = HtmlUtil.parseAsHtml(section.getText().getDivAsString()); ourLog.info("Narrative:\n{}", narrativeHtml.asXml()); @@ -304,16 +311,11 @@ public class IpsGeneratorSvcImplTest { registerRemainingResourceDaos(); // Test - Bundle outcome = (Bundle) mySvc.generateIps(new SystemRequestDetails(), new IdType("Patient/123")); + Bundle outcome = (Bundle) mySvc.generateIps(new SystemRequestDetails(), new IdType(PATIENT_ID)); // Verify Composition compositions = (Composition) outcome.getEntry().get(0).getResource(); - Composition.SectionComponent section = compositions - .getSection() - .stream() - .filter(t -> t.getTitle().equals(myStrategy.getSectionRegistry().getSection(IpsSectionEnum.MEDICAL_DEVICES).getTitle())) - .findFirst() - .orElseThrow(); + Composition.SectionComponent section = findSection(compositions, IpsSectionEnum.MEDICAL_DEVICES); HtmlPage narrativeHtml = HtmlUtil.parseAsHtml(section.getText().getDivAsString()); ourLog.info("Narrative:\n{}", narrativeHtml.asXml()); @@ -356,16 +358,11 @@ public class IpsGeneratorSvcImplTest { registerRemainingResourceDaos(); // Test - Bundle outcome = (Bundle) mySvc.generateIps(new SystemRequestDetails(), new IdType("Patient/123")); + Bundle outcome = (Bundle) mySvc.generateIps(new SystemRequestDetails(), new IdType(PATIENT_ID)); // Verify Composition compositions = (Composition) outcome.getEntry().get(0).getResource(); - Composition.SectionComponent section = compositions - .getSection() - .stream() - .filter(t -> t.getTitle().equals(myStrategy.getSectionRegistry().getSection(IpsSectionEnum.IMMUNIZATIONS).getTitle())) - .findFirst() - .orElseThrow(); + Composition.SectionComponent section = findSection(compositions, IpsSectionEnum.IMMUNIZATIONS); HtmlPage narrativeHtml = HtmlUtil.parseAsHtml(section.getText().getDivAsString()); ourLog.info("Narrative:\n{}", narrativeHtml.asXml()); @@ -383,10 +380,82 @@ public class IpsGeneratorSvcImplTest { assertThat(row.getCell(6).asNormalizedText(), containsString("2023")); } + + @Test + public void testReferencesUpdatedInSecondaryInclusions() { + // Setup Patient + registerPatientDaoWithRead(); + + // Setup Medication + MedicationStatement + Encounter encounter = new Encounter(); + encounter.setId(new IdType(ENCOUNTER_ID)); + encounter.setSubject(new Reference(PATIENT_ID)); + ResourceMetadataKeyEnum.ENTRY_SEARCH_MODE.put(encounter, BundleEntrySearchModeEnum.INCLUDE); + + Condition conditionActive = new Condition(); + conditionActive.setId("Condition/conditionActive"); + conditionActive.getClinicalStatus().addCoding() + .setSystem("http://terminology.hl7.org/CodeSystem/condition-clinical") + .setCode("active"); + conditionActive.setSubject(new Reference(PATIENT_ID)); + conditionActive.setEncounter(new Reference(ENCOUNTER_ID)); + ResourceMetadataKeyEnum.ENTRY_SEARCH_MODE.put(conditionActive, BundleEntrySearchModeEnum.MATCH); + + Condition conditionResolved = new Condition(); + conditionResolved.setId("Condition/conditionResolved"); + conditionResolved.getClinicalStatus().addCoding() + .setSystem("http://terminology.hl7.org/CodeSystem/condition-clinical") + .setCode("resolved"); + conditionResolved.setSubject(new Reference(PATIENT_ID)); + conditionResolved.setEncounter(new Reference(ENCOUNTER_ID)); + ResourceMetadataKeyEnum.ENTRY_SEARCH_MODE.put(conditionResolved, BundleEntrySearchModeEnum.MATCH); + + // Conditions will be loaded from two sections (problem list and illness history) so + // we return an active condition the first time and a resolved one the second + IFhirResourceDao conditionDao = registerResourceDaoWithNoData(Condition.class); + when(conditionDao.search(any(), any())).thenReturn( + new SimpleBundleProvider(Lists.newArrayList(conditionActive, encounter)), + new SimpleBundleProvider(Lists.newArrayList(conditionResolved, encounter)) + ); + + registerRemainingResourceDaos(); + + // Test + Bundle outcome = (Bundle) mySvc.generateIps(new SystemRequestDetails(), new IdType(PATIENT_ID)); + + // Verify cross-references + Patient addedPatient = findEntryResource(outcome, Patient.class, 0, 1); + assertThat(addedPatient.getId(), startsWith("urn:uuid:")); + Condition addedCondition = findEntryResource(outcome, Condition.class, 0, 2); + assertThat(addedCondition.getId(), startsWith("urn:uuid:")); + Condition addedCondition2 = findEntryResource(outcome, Condition.class, 1, 2); + assertThat(addedCondition2.getId(), startsWith("urn:uuid:")); + Encounter addedEncounter = findEntryResource(outcome, Encounter.class, 0, 1); + assertThat(addedEncounter.getId(), startsWith("urn:uuid:")); + MedicationStatement addedMedicationStatement = findEntryResource(outcome, MedicationStatement.class, 0, 1); + assertThat(addedMedicationStatement.getId(), startsWith("urn:uuid:")); + assertEquals("no-medication-info", addedMedicationStatement.getMedicationCodeableConcept().getCodingFirstRep().getCode()); + assertEquals(addedPatient.getId(), addedCondition.getSubject().getReference()); + assertEquals(addedEncounter.getId(), addedCondition.getEncounter().getReference()); + assertEquals(addedPatient.getId(), addedEncounter.getSubject().getReference()); + assertEquals(addedPatient.getId(), addedMedicationStatement.getSubject().getReference()); + + // Verify sections + ourLog.info("Resource: {}", myFhirContext.newJsonParser().setPrettyPrint(true).encodeResourceToString(outcome)); + verify(conditionDao, times(2)).search(any(), any()); + Composition composition = (Composition) outcome.getEntry().get(0).getResource(); + Composition.SectionComponent problemListSection = findSection(composition, IpsSectionEnum.PROBLEM_LIST); + assertEquals(addedCondition.getId(), problemListSection.getEntry().get(0).getReference()); + assertEquals(1, problemListSection.getEntry().size()); + Composition.SectionComponent illnessHistorySection = findSection(composition, IpsSectionEnum.ILLNESS_HISTORY); + assertEquals(addedCondition2.getId(), illnessHistorySection.getEntry().get(0).getReference()); + assertEquals(1, illnessHistorySection.getEntry().size()); + } + private void registerPatientDaoWithRead() { IFhirResourceDao patientDao = registerResourceDaoWithNoData(Patient.class); Patient patient = new Patient(); - patient.setId("Patient/123"); + patient.setId(PATIENT_ID); when(patientDao.read(any(), any())).thenReturn(patient); } @@ -432,12 +501,11 @@ public class IpsGeneratorSvcImplTest { @Nonnull private static List toEntryResourceTypeStrings(Bundle outcome) { - List contentResourceTypes = outcome + return outcome .getEntry() .stream() .map(t -> t.getResource().getResourceType().name()) .collect(Collectors.toList()); - return contentResourceTypes; } @Nonnull diff --git a/hapi-fhir-jpaserver-ips/src/test/resources/tiny-patient-everything.json.gz b/hapi-fhir-jpaserver-ips/src/test/resources/tiny-patient-everything.json.gz new file mode 100644 index 0000000000000000000000000000000000000000..92194281a39403582ed2f2e4ee245731acd8d54d GIT binary patch literal 1796 zcmV+f2mAORiwFor$=_oF19WL_c`a~ZbZKR7bS-6eWpa6RXlZU|E^2dcZUF6BTW{Mo z6n^io5VXB*wy3KuBh8RY+oW5PCUpa>YcbFgWwE10gQSwUMgIFJN|tF`c9O*n60Kpis zzBDaY_hc2|(AXMmzdhJFJK8a}tikq{CHHJ^2{<5VZtELH$B2nZzgQ`Bivf)%@(+_g z@%CXXtAG=X*p?+Pi(9tsIIioJ*OrniWq0COmXX(jTYL<&?LT0KjAJUBSvsQbYz>%I zE$*c#%OI{-)bBnVVPYJ^IIr(7+1i(BG-zTBFcay5MGzP#k)Q*_3mqAvC3Yj3uhM#n2FQ!4!fkVQu>b zB)QUEWx4jM#G;ack-!&)kYG8g?`Cj>7X3_$OimQjVM6n42z6USsU=fe%p=J^Nb-zn zd~7f%5J3?gEoz^II!+nGaDmA{lqmmBO!oWv^W<_MCRUQ-pjsC)@u z01EhmU?u>|4qQ<#WlrYjCx7AkvHo6gl)RDR65RSV^r)=3q+>ufio zF)G6oa-kGf4~4rj>>kZxTy&D<0=v%ftr)i6y2!D*rkfeoy$!>Hz5{wL==q&?H}Kap zZ2J21!He+S>+`eMboa#hHVk_(DM%4zMVzbXA(H)rBS_v(t!o}dG?q`)g+6Rz2Z7iK zXOz(4q@9wE@?=kT$6F<6Mbjd+rq;B;N;@iT6(!V5*E1Z?{FQkb(zz%3-F)Sl1W??@ zSwbxyiDpl1FYr46g!8L0=3@dCmi93mW|U(-=dD(*s=mvDIz{keZYj}u-%wUX;`n|5 zJOG@Pp-AAzH$`!z$!N7GZ9J6gZrAl}0Nj+*xhwc*F3|5(`1Ao&lxJHbT&_kJ&V@#>Rzc23S4$f+I-5}awz&ik|}p*V{ch(>GBt}8L+ zuWZg;dGIi#!f`RCNXEK}d{@cer)70B3&-sx?I=l*nk|a4yN^fJ=mjH#aySA zsOEcI}N~ z*M7q89Cm$~lh*2?aFyq6v*L%n&gyu}BR_h!LgolqP%1pyMLrkZgKNd{_)` z9wl1EMq`>4elEW?n76pPn71#dUQn+KTEXI~R?*@O2_-l(=1Xg88)miBLR!mtI_uf~ zTr*91Z!|g>YVA>H>~WJ5I15jzrI##o*?F_+?1bPh$$7jNqK%z?E5@x5(D=bAd;qew z{hsT$JK_2dPQknLi-W^U!cILr*@wpu^_3#Z8U8F4wI$%Kl25pGp}tr&zSlno0N9N$ z=4$S*-bpU7)N#XSit5vad9LgkZUCAnN`}K)36rE5lSxbMX|O-8X!Y(V_-`~BNFRdD zO$M5_@3C2*ruqk&2<)$!>H&C~>hF(Tf1}v-pRoI*PWATFRR1VbJ$RbxS7xW{f1gwR mGVOLYO1qsW+WnEgVSLT_p=tD*ym+1av$A literal 0 HcmV?d00001 diff --git a/hapi-fhir-jpaserver-uhnfhirtest/pom.xml b/hapi-fhir-jpaserver-uhnfhirtest/pom.xml index f6180eaca46..49e2221ba3a 100644 --- a/hapi-fhir-jpaserver-uhnfhirtest/pom.xml +++ b/hapi-fhir-jpaserver-uhnfhirtest/pom.xml @@ -1,5 +1,5 @@ + xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> 4.0.0 @@ -48,11 +48,16 @@ ${project.version} classes - - ca.uhn.hapi.fhir - hapi-fhir-server-openapi - ${project.version} - + + ca.uhn.hapi.fhir + hapi-fhir-server-openapi + ${project.version} + + + ca.uhn.hapi.fhir + hapi-fhir-jpaserver-ips + ${project.version} + com.helger diff --git a/hapi-fhir-jpaserver-uhnfhirtest/src/main/java/ca/uhn/fhirtest/TestRestfulServer.java b/hapi-fhir-jpaserver-uhnfhirtest/src/main/java/ca/uhn/fhirtest/TestRestfulServer.java index 1cf2d86b133..f1eb9ff5465 100644 --- a/hapi-fhir-jpaserver-uhnfhirtest/src/main/java/ca/uhn/fhirtest/TestRestfulServer.java +++ b/hapi-fhir-jpaserver-uhnfhirtest/src/main/java/ca/uhn/fhirtest/TestRestfulServer.java @@ -12,6 +12,7 @@ import ca.uhn.fhir.jpa.bulk.export.provider.BulkDataExportProvider; import ca.uhn.fhir.jpa.delete.ThreadSafeResourceDeleterSvc; import ca.uhn.fhir.jpa.graphql.GraphQLProvider; import ca.uhn.fhir.jpa.interceptor.CascadingDeleteInterceptor; +import ca.uhn.fhir.jpa.ips.provider.IpsOperationProvider; import ca.uhn.fhir.jpa.provider.DiffProvider; import ca.uhn.fhir.jpa.provider.JpaCapabilityStatementProvider; import ca.uhn.fhir.jpa.provider.JpaConformanceProviderDstu2; @@ -152,6 +153,7 @@ public class TestRestfulServer extends RestfulServer { setServerConformanceProvider(confProvider); providers.add(myAppCtx.getBean(TerminologyUploaderProvider.class)); providers.add(myAppCtx.getBean(GraphQLProvider.class)); + providers.add(myAppCtx.getBean(IpsOperationProvider.class)); break; } case "R4B": { diff --git a/hapi-fhir-jpaserver-uhnfhirtest/src/main/java/ca/uhn/fhirtest/config/TestR4Config.java b/hapi-fhir-jpaserver-uhnfhirtest/src/main/java/ca/uhn/fhirtest/config/TestR4Config.java index 48821cd3ecd..2eb94a15a68 100644 --- a/hapi-fhir-jpaserver-uhnfhirtest/src/main/java/ca/uhn/fhirtest/config/TestR4Config.java +++ b/hapi-fhir-jpaserver-uhnfhirtest/src/main/java/ca/uhn/fhirtest/config/TestR4Config.java @@ -2,9 +2,15 @@ package ca.uhn.fhirtest.config; import ca.uhn.fhir.context.FhirContext; import ca.uhn.fhir.jpa.api.config.DaoConfig; +import ca.uhn.fhir.jpa.api.dao.DaoRegistry; import ca.uhn.fhir.jpa.config.HapiJpaConfig; import ca.uhn.fhir.jpa.config.r4.JpaR4Config; import ca.uhn.fhir.jpa.config.util.HapiEntityManagerFactoryUtil; +import ca.uhn.fhir.jpa.ips.api.IIpsGenerationStrategy; +import ca.uhn.fhir.jpa.ips.generator.IIpsGeneratorSvc; +import ca.uhn.fhir.jpa.ips.generator.IpsGeneratorSvcImpl; +import ca.uhn.fhir.jpa.ips.provider.IpsOperationProvider; +import ca.uhn.fhir.jpa.ips.strategy.DefaultIpsGenerationStrategy; import ca.uhn.fhir.jpa.model.dialect.HapiFhirH2Dialect; import ca.uhn.fhir.jpa.model.dialect.HapiFhirPostgres94Dialect; import ca.uhn.fhir.jpa.model.entity.ModelConfig; @@ -196,5 +202,19 @@ public class TestR4Config { return new PropertySourcesPlaceholderConfigurer(); } + @Bean + public IIpsGenerationStrategy ipsGenerationStrategy() { + return new DefaultIpsGenerationStrategy(); + } + + @Bean + public IIpsGeneratorSvc ipsGeneratorSvc(FhirContext theFhirContext, IIpsGenerationStrategy theGenerationStrategy, DaoRegistry theDaoRegistry) { + return new IpsGeneratorSvcImpl(theFhirContext, theGenerationStrategy, theDaoRegistry); + } + + @Bean + public IpsOperationProvider ipsOperationProvider(IIpsGeneratorSvc theIpsGeneratorSvc) { + return new IpsOperationProvider(theIpsGeneratorSvc); + } }