diff --git a/hapi-fhir-docs/src/main/resources/ca/uhn/hapi/fhir/changelog/7_6_0/6305-search-missing-qualifier-does-not-work-reference-parameters.yaml b/hapi-fhir-docs/src/main/resources/ca/uhn/hapi/fhir/changelog/7_6_0/6305-search-missing-qualifier-does-not-work-reference-parameters.yaml new file mode 100644 index 00000000000..da98735c073 --- /dev/null +++ b/hapi-fhir-docs/src/main/resources/ca/uhn/hapi/fhir/changelog/7_6_0/6305-search-missing-qualifier-does-not-work-reference-parameters.yaml @@ -0,0 +1,6 @@ +--- +type: fix +issue: 6305 +title: "Previously, when having StorageSettings#getIndexMissingFields() == IndexEnabledEnum.DISABLED (default value) +and attempting to search with the missing qualifier against a resource type with multiple search parameters of type reference, +the returned results would be incorrect. This has been fixed." \ No newline at end of file diff --git a/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/search/builder/predicate/ResourceLinkPredicateBuilder.java b/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/search/builder/predicate/ResourceLinkPredicateBuilder.java index ab4b1afdefc..79981c2ca7f 100644 --- a/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/search/builder/predicate/ResourceLinkPredicateBuilder.java +++ b/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/search/builder/predicate/ResourceLinkPredicateBuilder.java @@ -800,14 +800,19 @@ public Condition createPredicateParamMissingValue(MissingQueryParameterPredicate subquery.addCustomColumns(1); subquery.addFromTable(getTable()); + String resourceType = theParams.getResourceTablePredicateBuilder().getResourceType(); + RuntimeSearchParam paramDefinition = + mySearchParamRegistry.getRuntimeSearchParam(resourceType, theParams.getParamName()); + List pathList = paramDefinition.getPathsSplitForResourceType(resourceType); + Condition subQueryCondition = ComboCondition.and( BinaryCondition.equalTo( getResourceIdColumn(), theParams.getResourceTablePredicateBuilder().getResourceIdColumn()), - BinaryCondition.equalTo( - getResourceTypeColumn(), - generatePlaceholder( - theParams.getResourceTablePredicateBuilder().getResourceType()))); + BinaryCondition.equalTo(getResourceTypeColumn(), generatePlaceholder(resourceType)), + ComboCondition.or(pathList.stream() + .map(path -> BinaryCondition.equalTo(getColumnSourcePath(), generatePlaceholder(path))) + .toArray(BinaryCondition[]::new))); subquery.addCondition(subQueryCondition); diff --git a/hapi-fhir-jpaserver-test-r4/src/test/java/ca/uhn/fhir/jpa/dao/r4/FhirResourceDaoR4SearchMissingTest.java b/hapi-fhir-jpaserver-test-r4/src/test/java/ca/uhn/fhir/jpa/dao/r4/FhirResourceDaoR4SearchMissingTest.java index 742fb1ed48d..811ea570e2f 100644 --- a/hapi-fhir-jpaserver-test-r4/src/test/java/ca/uhn/fhir/jpa/dao/r4/FhirResourceDaoR4SearchMissingTest.java +++ b/hapi-fhir-jpaserver-test-r4/src/test/java/ca/uhn/fhir/jpa/dao/r4/FhirResourceDaoR4SearchMissingTest.java @@ -1,9 +1,10 @@ package ca.uhn.fhir.jpa.dao.r4; -import static org.junit.jupiter.api.Assertions.assertEquals; -import ca.uhn.fhir.i18n.Msg; -import ca.uhn.fhir.jpa.api.config.JpaStorageSettings; import ca.uhn.fhir.jpa.model.entity.NormalizedQuantitySearchLevel; +import ca.uhn.fhir.jpa.model.entity.ResourceIndexedSearchParamCoords; +import ca.uhn.fhir.jpa.model.entity.ResourceIndexedSearchParamQuantity; +import ca.uhn.fhir.jpa.model.entity.ResourceIndexedSearchParamQuantityNormalized; +import ca.uhn.fhir.jpa.model.entity.StorageSettings; import ca.uhn.fhir.jpa.searchparam.SearchParameterMap; import ca.uhn.fhir.jpa.test.BaseJpaR4Test; import ca.uhn.fhir.rest.api.server.IBundleProvider; @@ -12,7 +13,6 @@ import ca.uhn.fhir.rest.param.ReferenceParam; import ca.uhn.fhir.rest.param.StringParam; import ca.uhn.fhir.rest.param.TokenParam; -import ca.uhn.fhir.rest.server.exceptions.MethodNotAllowedException; import org.hl7.fhir.instance.model.api.IIdType; import org.hl7.fhir.r4.model.DateType; import org.hl7.fhir.r4.model.DecimalType; @@ -26,513 +26,528 @@ import org.hl7.fhir.r4.model.Task; import org.junit.jupiter.api.AfterEach; import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Nested; import org.junit.jupiter.api.Test; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; import java.util.List; import java.util.stream.Collectors; import static org.assertj.core.api.Assertions.assertThat; -public class FhirResourceDaoR4SearchMissingTest extends BaseJpaR4Test { - private static final Logger ourLog = LoggerFactory.getLogger(FhirResourceDaoR4SearchMissingTest.class); +public class FhirResourceDaoR4SearchMissingTest { - @BeforeEach - public void beforeResetMissing() { - myStorageSettings.setIndexMissingFields(JpaStorageSettings.IndexEnabledEnum.ENABLED); - } - - @AfterEach - public void afterResetSearch() { - myStorageSettings.setNormalizedQuantitySearchLevel(NormalizedQuantitySearchLevel.NORMALIZED_QUANTITY_SEARCH_NOT_SUPPORTED); - } - - @Test - public void testIndexMissingFieldsDisabledDontAllowInSearch_NonReference() { - myStorageSettings.setIndexMissingFields(JpaStorageSettings.IndexEnabledEnum.DISABLED); - - SearchParameterMap params = new SearchParameterMap(); - params.add(Patient.SP_ACTIVE, new StringParam().setMissing(true)); - try { - myPatientDao.search(params); - } catch (MethodNotAllowedException e) { - assertEquals(Msg.code(985) + ":missing modifier is disabled on this server", e.getMessage()); - } - } - - @Test - public void testIndexMissingFieldsDisabledDontAllowInSearch_Reference() { - myStorageSettings.setIndexMissingFields(JpaStorageSettings.IndexEnabledEnum.DISABLED); - - SearchParameterMap params = new SearchParameterMap(); - params.add(Patient.SP_ORGANIZATION, new StringParam().setMissing(true)); - try { - myPatientDao.search(params); - } catch (MethodNotAllowedException e) { - assertEquals(Msg.code(985) + ":missing modifier is disabled on this server", e.getMessage()); - } - } - - @Test - public void testIndexMissingFieldsDisabledDontCreateIndexes() { - myStorageSettings.setIndexMissingFields(JpaStorageSettings.IndexEnabledEnum.DISABLED); - Organization org = new Organization(); - org.setActive(true); - myOrganizationDao.create(org, mySrd).getId().toUnqualifiedVersionless(); - - runInTransaction(() -> { - assertThat(mySearchParamPresentDao.findAll()).isEmpty(); - assertThat(myResourceIndexedSearchParamStringDao.findAll()).isEmpty(); - assertThat(myResourceIndexedSearchParamDateDao.findAll()).isEmpty(); - assertThat(myResourceIndexedSearchParamTokenDao.findAll()).hasSize(1); - assertThat(myResourceIndexedSearchParamQuantityDao.findAll()).isEmpty(); - }); - - } - - @Test - public void testIndexMissingFieldsDisabledDontCreateIndexesWithNormalizedQuantitySearchSupported() { - - myStorageSettings.setIndexMissingFields(JpaStorageSettings.IndexEnabledEnum.DISABLED); - myStorageSettings.setNormalizedQuantitySearchLevel(NormalizedQuantitySearchLevel.NORMALIZED_QUANTITY_SEARCH_SUPPORTED); - Organization org = new Organization(); - org.setActive(true); - myOrganizationDao.create(org, mySrd).getId().toUnqualifiedVersionless(); - - runInTransaction(() -> { - assertThat(mySearchParamPresentDao.findAll()).isEmpty(); - assertThat(myResourceIndexedSearchParamStringDao.findAll()).isEmpty(); - assertThat(myResourceIndexedSearchParamDateDao.findAll()).isEmpty(); - assertThat(myResourceIndexedSearchParamTokenDao.findAll()).hasSize(1); - assertThat(myResourceIndexedSearchParamQuantityDao.findAll()).isEmpty(); - }); - - } - - @Test - public void testIndexMissingFieldsDisabledDontCreateIndexesWithNormalizedQuantityStorageSupported() { - - myStorageSettings.setIndexMissingFields(JpaStorageSettings.IndexEnabledEnum.DISABLED); - myStorageSettings.setNormalizedQuantitySearchLevel(NormalizedQuantitySearchLevel.NORMALIZED_QUANTITY_STORAGE_SUPPORTED); - Organization org = new Organization(); - org.setActive(true); - myOrganizationDao.create(org, mySrd).getId().toUnqualifiedVersionless(); - - runInTransaction(() -> { - assertThat(mySearchParamPresentDao.findAll()).isEmpty(); - assertThat(myResourceIndexedSearchParamStringDao.findAll()).isEmpty(); - assertThat(myResourceIndexedSearchParamDateDao.findAll()).isEmpty(); - assertThat(myResourceIndexedSearchParamTokenDao.findAll()).hasSize(1); - assertThat(myResourceIndexedSearchParamQuantityDao.findAll()).isEmpty(); - }); - - } - - @SuppressWarnings("unused") - @Test - public void testSearchResourceReferenceMissingChain() { - IIdType oid1; - { - Organization org = new Organization(); - org.setActive(true); - oid1 = myOrganizationDao.create(org, mySrd).getId().toUnqualifiedVersionless(); - } - IIdType tid1; - { - Task task = new Task(); - task.setRequester(new Reference(oid1)); - tid1 = myTaskDao.create(task, mySrd).getId().toUnqualifiedVersionless(); - } - IIdType tid2; - { - Task task = new Task(); - task.setOwner(new Reference(oid1)); - tid2 = myTaskDao.create(task, mySrd).getId().toUnqualifiedVersionless(); + @Nested + class IndexMissingDisabledTests extends MissingTests { + @BeforeEach + public void before() { + myStorageSettings.setIndexMissingFields(StorageSettings.IndexEnabledEnum.DISABLED); } - IIdType oid2; - { + @Test + public void testIndexMissingFieldsDisabledDontCreateIndexes() { Organization org = new Organization(); org.setActive(true); - org.setName("NAME"); - oid2 = myOrganizationDao.create(org, mySrd).getId().toUnqualifiedVersionless(); - } - IIdType tid3; - { - Task task = new Task(); - task.setRequester(new Reference(oid2)); - tid3 = myTaskDao.create(task, mySrd).getId().toUnqualifiedVersionless(); - } - - SearchParameterMap map; - List ids; - - map = new SearchParameterMap(); - map.add(Organization.SP_NAME, new StringParam().setMissing(true)); - ids = toUnqualifiedVersionlessIds(myOrganizationDao.search(map)); - assertThat(ids).containsExactly(oid1); - - ourLog.info("Starting Search 2"); - - map = new SearchParameterMap(); - map.add(Task.SP_REQUESTER, new ReferenceParam("Organization", "name:missing", "true")); - ids = toUnqualifiedVersionlessIds(myTaskDao.search(map)); - assertThat(ids).containsExactly(tid1); // NOT tid2 - - map = new SearchParameterMap(); - map.add(Task.SP_REQUESTER, new ReferenceParam("Organization", "name:missing", "false")); - ids = toUnqualifiedVersionlessIds(myTaskDao.search(map)); - assertThat(ids).containsExactly(tid3); + myOrganizationDao.create(org, mySrd).getId().toUnqualifiedVersionless(); - map = new SearchParameterMap(); - map.add(Patient.SP_ORGANIZATION, new ReferenceParam("Organization", "name:missing", "true")); - ids = toUnqualifiedVersionlessIds(myPatientDao.search(map)); - assertThat(ids).isEmpty(); + runInTransaction(() -> { + assertThat(mySearchParamPresentDao.findAll()).isEmpty(); + assertThat(myResourceIndexedSearchParamStringDao.findAll()).isEmpty(); + assertThat(myResourceIndexedSearchParamDateDao.findAll()).isEmpty(); + assertThat(myResourceIndexedSearchParamTokenDao.findAll()).hasSize(1); + assertThat(myResourceIndexedSearchParamQuantityDao.findAll()).isEmpty(); + }); - } - - @Test - public void testSearchWithMissingDate() { - IIdType orgId = myOrganizationDao.create(new Organization(), mySrd).getId(); - IIdType notMissing; - IIdType missing; - { - Patient patient = new Patient(); - patient.addIdentifier().setSystem("urn:system").setValue("001"); - missing = myPatientDao.create(patient, mySrd).getId().toUnqualifiedVersionless(); - } - { - Patient patient = new Patient(); - patient.addIdentifier().setSystem("urn:system").setValue("002"); - patient.addName().setFamily("Tester_testSearchStringParam").addGiven("John"); - patient.setBirthDateElement(new DateType("2011-01-01")); - patient.getManagingOrganization().setReferenceElement(orgId); - notMissing = myPatientDao.create(patient, mySrd).getId().toUnqualifiedVersionless(); - } - // Date Param - { - SearchParameterMap params = new SearchParameterMap(); - params.setLoadSynchronous(true); - DateParam param = new DateParam(); - param.setMissing(false); - params.add(Patient.SP_BIRTHDATE, param); - List patients = toUnqualifiedVersionlessIds(myPatientDao.search(params)); - assertThat(patients).containsSubsequence(notMissing); - assertThat(patients).doesNotContainSubsequence(missing); - } - { - SearchParameterMap params = new SearchParameterMap(); - params.setLoadSynchronous(true); - DateParam param = new DateParam(); - param.setMissing(true); - params.add(Patient.SP_BIRTHDATE, param); - List patients = toUnqualifiedVersionlessIds(myPatientDao.search(params)); - assertThat(patients).containsSubsequence(missing); - assertThat(patients).doesNotContainSubsequence(notMissing); } - } - - @Test - public void testSearchWithMissingCoords() { - String locId = myLocationDao.create(new Location(), mySrd).getId().toUnqualifiedVersionless().getValue(); - String locId2 = myLocationDao.create(new Location().setPosition(new Location.LocationPositionComponent(new DecimalType(10), new DecimalType(10))), mySrd).getId().toUnqualifiedVersionless().getValue(); - runInTransaction(() -> { - ourLog.info("Coords:\n * {}", myResourceIndexedSearchParamCoordsDao.findAll().stream().map(t -> t.toString()).collect(Collectors.joining("\n * "))); - }); - - { - SearchParameterMap params = new SearchParameterMap(); - params.setLoadSynchronous(true); - TokenParam param = new TokenParam(); - param.setMissing(true); - params.add(Location.SP_NEAR, param); - myCaptureQueriesListener.clear(); - List patients = toUnqualifiedVersionlessIdValues(myLocationDao.search(params)); - myCaptureQueriesListener.logSelectQueriesForCurrentThread(0); - assertThat(patients).containsSubsequence(locId); - assertThat(patients).doesNotContainSubsequence(locId2); - } - { - SearchParameterMap params = new SearchParameterMap(); - params.setLoadSynchronous(true); - TokenParam param = new TokenParam(); - param.setMissing(false); - params.add(Location.SP_NEAR, param); - List patients = toUnqualifiedVersionlessIdValues(myLocationDao.search(params)); - assertThat(patients).containsSubsequence(locId2); - assertThat(patients).doesNotContainSubsequence(locId); - } - } - - @Test - public void testSearchWithMissingDate2() { - MedicationRequest mr1 = new MedicationRequest(); - mr1.addCategory().addCoding().setSystem("urn:medicationroute").setCode("oral"); - mr1.addDosageInstruction().getTiming().addEventElement().setValueAsString("2017-01-01"); - IIdType id1 = myMedicationRequestDao.create(mr1).getId().toUnqualifiedVersionless(); - - MedicationRequest mr2 = new MedicationRequest(); - mr2.addCategory().addCoding().setSystem("urn:medicationroute").setCode("oral"); - IIdType id2 = myMedicationRequestDao.create(mr2).getId().toUnqualifiedVersionless(); - - SearchParameterMap map = new SearchParameterMap(); - map.add(MedicationRequest.SP_DATE, new DateParam().setMissing(true)); - IBundleProvider results = myMedicationRequestDao.search(map); - List ids = toUnqualifiedVersionlessIdValues(results); - - assertThat(ids).containsExactly(id2.getValue()); + @Test + public void testIndexMissingFieldsDisabledDontCreateIndexesWithNormalizedQuantitySearchSupported() { + myStorageSettings.setNormalizedQuantitySearchLevel(NormalizedQuantitySearchLevel.NORMALIZED_QUANTITY_SEARCH_SUPPORTED); + Organization org = new Organization(); + org.setActive(true); + myOrganizationDao.create(org, mySrd).getId().toUnqualifiedVersionless(); - } + runInTransaction(() -> { + assertThat(mySearchParamPresentDao.findAll()).isEmpty(); + assertThat(myResourceIndexedSearchParamStringDao.findAll()).isEmpty(); + assertThat(myResourceIndexedSearchParamDateDao.findAll()).isEmpty(); + assertThat(myResourceIndexedSearchParamTokenDao.findAll()).hasSize(1); + assertThat(myResourceIndexedSearchParamQuantityDao.findAll()).isEmpty(); + }); - @Test - public void testSearchWithMissingQuantity() { - IIdType notMissing; - IIdType missing; - { - Observation obs = new Observation(); - obs.addIdentifier().setSystem("urn:system").setValue("001"); - missing = myObservationDao.create(obs, mySrd).getId().toUnqualifiedVersionless(); - } - { - Observation obs = new Observation(); - obs.addIdentifier().setSystem("urn:system").setValue("002"); - obs.setValue(new Quantity(123)); - notMissing = myObservationDao.create(obs, mySrd).getId().toUnqualifiedVersionless(); - } - // Quantity Param - { - SearchParameterMap params = new SearchParameterMap(); - params.setLoadSynchronous(true); - QuantityParam param = new QuantityParam(); - param.setMissing(false); - params.add(Observation.SP_VALUE_QUANTITY, param); - List patients = toUnqualifiedVersionlessIds(myObservationDao.search(params)); - assertThat(patients).doesNotContainSubsequence(missing); - assertThat(patients).containsSubsequence(notMissing); - } - { - SearchParameterMap params = new SearchParameterMap(); - params.setLoadSynchronous(true); - QuantityParam param = new QuantityParam(); - param.setMissing(true); - params.add(Observation.SP_VALUE_QUANTITY, param); - List patients = toUnqualifiedVersionlessIds(myObservationDao.search(params)); - assertThat(patients).containsSubsequence(missing); - assertThat(patients).doesNotContainSubsequence(notMissing); } - } - - @Test - public void testSearchWithMissingQuantityWithNormalizedQuantitySearchSupported() { - myStorageSettings.setNormalizedQuantitySearchLevel(NormalizedQuantitySearchLevel.NORMALIZED_QUANTITY_SEARCH_SUPPORTED); - IIdType notMissing; - IIdType missing; - { - Observation obs = new Observation(); - obs.addIdentifier().setSystem("urn:system").setValue("001"); - missing = myObservationDao.create(obs, mySrd).getId().toUnqualifiedVersionless(); - } - { - Observation obs = new Observation(); - obs.addIdentifier().setSystem("urn:system").setValue("002"); - obs.setValue(new Quantity(123)); - notMissing = myObservationDao.create(obs, mySrd).getId().toUnqualifiedVersionless(); - } + @Test + public void testIndexMissingFieldsDisabledDontCreateIndexesWithNormalizedQuantityStorageSupported() { + myStorageSettings.setNormalizedQuantitySearchLevel(NormalizedQuantitySearchLevel.NORMALIZED_QUANTITY_STORAGE_SUPPORTED); + Organization org = new Organization(); + org.setActive(true); + myOrganizationDao.create(org, mySrd).getId().toUnqualifiedVersionless(); - runInTransaction(() -> { - ourLog.info("Quantity Indexes:\n * {}", myResourceIndexedSearchParamQuantityDao.findAll().stream().filter(t -> t.getParamName().equals("value-quantity")).map(t -> t.toString()).collect(Collectors.joining("\n * "))); - ourLog.info("Normalized Quantity Indexes:\n * {}", myResourceIndexedSearchParamQuantityNormalizedDao.findAll().stream().filter(t -> t.getParamName().equals("value-quantity")).map(t -> t.toString()).collect(Collectors.joining("\n * "))); - }); + runInTransaction(() -> { + assertThat(mySearchParamPresentDao.findAll()).isEmpty(); + assertThat(myResourceIndexedSearchParamStringDao.findAll()).isEmpty(); + assertThat(myResourceIndexedSearchParamDateDao.findAll()).isEmpty(); + assertThat(myResourceIndexedSearchParamTokenDao.findAll()).hasSize(1); + assertThat(myResourceIndexedSearchParamQuantityDao.findAll()).isEmpty(); + }); - // Quantity Param - { - SearchParameterMap params = new SearchParameterMap(); - params.setLoadSynchronous(true); - QuantityParam param = new QuantityParam(); - param.setMissing(false); - params.add(Observation.SP_VALUE_QUANTITY, param); - List patients = toUnqualifiedVersionlessIds(myObservationDao.search(params)); - assertThat(patients).doesNotContainSubsequence(missing); - assertThat(patients).containsSubsequence(notMissing); - } - { - SearchParameterMap params = new SearchParameterMap(); - params.setLoadSynchronous(true); - QuantityParam param = new QuantityParam(); - param.setMissing(true); - params.add(Observation.SP_VALUE_QUANTITY, param); - myCaptureQueriesListener.clear(); - List patients = toUnqualifiedVersionlessIds(myObservationDao.search(params)); - myCaptureQueriesListener.logSelectQueries(); - assertThat(patients).containsSubsequence(missing); - assertThat(patients).doesNotContainSubsequence(notMissing); } - } - @Test - public void testSearchWithMissingQuantityWithNormalizedQuantityStorageSupported() { + @Nested + class IndexMissingEnabledTests extends MissingTests { + @BeforeEach + public void before() { + myStorageSettings.setIndexMissingFields(StorageSettings.IndexEnabledEnum.ENABLED); + } + + + @SuppressWarnings("unused") + @Test + public void testSearchResourceReferenceMissingChain() { + IIdType oid1; + { + Organization org = new Organization(); + org.setActive(true); + oid1 = myOrganizationDao.create(org, mySrd).getId().toUnqualifiedVersionless(); + } + IIdType tid1; + { + Task task = new Task(); + task.setRequester(new Reference(oid1)); + tid1 = myTaskDao.create(task, mySrd).getId().toUnqualifiedVersionless(); + } + { + Task task = new Task(); + task.setOwner(new Reference(oid1)); + myTaskDao.create(task, mySrd).getId().toUnqualifiedVersionless(); + } + + IIdType oid2; + { + Organization org = new Organization(); + org.setActive(true); + org.setName("NAME"); + oid2 = myOrganizationDao.create(org, mySrd).getId().toUnqualifiedVersionless(); + } + IIdType tid3; + { + Task task = new Task(); + task.setRequester(new Reference(oid2)); + tid3 = myTaskDao.create(task, mySrd).getId().toUnqualifiedVersionless(); + } + + SearchParameterMap map; + List ids; + + map = new SearchParameterMap(); + map.add(Organization.SP_NAME, new StringParam().setMissing(true)); + ids = toUnqualifiedVersionlessIds(myOrganizationDao.search(map, mySrd)); + assertThat(ids).containsExactly(oid1); + + ourLog.info("Starting Search 2"); + + map = new SearchParameterMap(); + map.add(Task.SP_REQUESTER, new ReferenceParam("Organization", "name:missing", "true")); + ids = toUnqualifiedVersionlessIds(myTaskDao.search(map, mySrd)); + assertThat(ids).containsExactly(tid1); // NOT tid2 + + map = new SearchParameterMap(); + map.add(Task.SP_REQUESTER, new ReferenceParam("Organization", "name:missing", "false")); + ids = toUnqualifiedVersionlessIds(myTaskDao.search(map, mySrd)); + assertThat(ids).containsExactly(tid3); + + map = new SearchParameterMap(); + map.add(Patient.SP_ORGANIZATION, new ReferenceParam("Organization", "name:missing", "true")); + ids = toUnqualifiedVersionlessIds(myPatientDao.search(map, mySrd)); + assertThat(ids).isEmpty(); - myStorageSettings.setNormalizedQuantitySearchLevel(NormalizedQuantitySearchLevel.NORMALIZED_QUANTITY_STORAGE_SUPPORTED); - IIdType notMissing; - IIdType missing; - { - Observation obs = new Observation(); - obs.addIdentifier().setSystem("urn:system").setValue("001"); - missing = myObservationDao.create(obs, mySrd).getId().toUnqualifiedVersionless(); - } - { - Observation obs = new Observation(); - obs.addIdentifier().setSystem("urn:system").setValue("002"); - obs.setValue(new Quantity(123)); - notMissing = myObservationDao.create(obs, mySrd).getId().toUnqualifiedVersionless(); - } - // Quantity Param - { - SearchParameterMap params = new SearchParameterMap(); - params.setLoadSynchronous(true); - QuantityParam param = new QuantityParam(); - param.setMissing(false); - params.add(Observation.SP_VALUE_QUANTITY, param); - List patients = toUnqualifiedVersionlessIds(myObservationDao.search(params)); - assertThat(patients).doesNotContainSubsequence(missing); - assertThat(patients).containsSubsequence(notMissing); - } - { - SearchParameterMap params = new SearchParameterMap(); - params.setLoadSynchronous(true); - QuantityParam param = new QuantityParam(); - param.setMissing(true); - params.add(Observation.SP_VALUE_QUANTITY, param); - List patients = toUnqualifiedVersionlessIds(myObservationDao.search(params)); - assertThat(patients).containsSubsequence(missing); - assertThat(patients).doesNotContainSubsequence(notMissing); } - } + static class MissingTests extends BaseJpaR4Test { + @AfterEach + public void after() { + myStorageSettings.setIndexMissingFields(new StorageSettings().getIndexMissingFields()); + myStorageSettings.setNormalizedQuantitySearchLevel(new StorageSettings().getNormalizedQuantitySearchLevel()); + + } + + @Test + public void testSearchWithMissingDate() { + IIdType orgId = myOrganizationDao.create(new Organization(), mySrd).getId(); + IIdType notMissing; + IIdType missing; + { + Patient patient = new Patient(); + patient.addIdentifier().setSystem("urn:system").setValue("001"); + missing = myPatientDao.create(patient, mySrd).getId().toUnqualifiedVersionless(); + } + { + Patient patient = new Patient(); + patient.addIdentifier().setSystem("urn:system").setValue("002"); + patient.addName().setFamily("Tester_testSearchStringParam").addGiven("John"); + patient.setBirthDateElement(new DateType("2011-01-01")); + patient.getManagingOrganization().setReferenceElement(orgId); + notMissing = myPatientDao.create(patient, mySrd).getId().toUnqualifiedVersionless(); + } + // Date Param + { + SearchParameterMap params = new SearchParameterMap(); + params.setLoadSynchronous(true); + DateParam param = new DateParam(); + param.setMissing(false); + params.add(Patient.SP_BIRTHDATE, param); + List patients = toUnqualifiedVersionlessIds(myPatientDao.search(params, mySrd)); + assertThat(patients).containsSubsequence(notMissing); + assertThat(patients).doesNotContainSubsequence(missing); + } + { + SearchParameterMap params = new SearchParameterMap(); + params.setLoadSynchronous(true); + DateParam param = new DateParam(); + param.setMissing(true); + params.add(Patient.SP_BIRTHDATE, param); + List patients = toUnqualifiedVersionlessIds(myPatientDao.search(params, mySrd)); + assertThat(patients).containsSubsequence(missing); + assertThat(patients).doesNotContainSubsequence(notMissing); + } + } + + @Test + public void testSearchWithMissingCoords() { + String locId = myLocationDao.create(new Location(), mySrd).getId().toUnqualifiedVersionless().getValue(); + String locId2 = myLocationDao.create(new Location().setPosition(new Location.LocationPositionComponent(new DecimalType(10), new DecimalType(10))), mySrd).getId().toUnqualifiedVersionless().getValue(); + + runInTransaction(() -> ourLog.info("Coords:\n * {}", + myResourceIndexedSearchParamCoordsDao.findAll().stream() + .map(ResourceIndexedSearchParamCoords::toString).collect(Collectors.joining("\n * ")) + ) + ); + + { + SearchParameterMap params = new SearchParameterMap(); + params.setLoadSynchronous(true); + TokenParam param = new TokenParam(); + param.setMissing(true); + params.add(Location.SP_NEAR, param); + myCaptureQueriesListener.clear(); + List patients = toUnqualifiedVersionlessIdValues(myLocationDao.search(params, mySrd)); + myCaptureQueriesListener.logSelectQueriesForCurrentThread(0); + assertThat(patients).containsSubsequence(locId); + assertThat(patients).doesNotContainSubsequence(locId2); + } + { + SearchParameterMap params = new SearchParameterMap(); + params.setLoadSynchronous(true); + TokenParam param = new TokenParam(); + param.setMissing(false); + params.add(Location.SP_NEAR, param); + List patients = toUnqualifiedVersionlessIdValues(myLocationDao.search(params, mySrd)); + assertThat(patients).containsSubsequence(locId2); + assertThat(patients).doesNotContainSubsequence(locId); + } + } + + @Test + public void testSearchWithMissingDate2() { + MedicationRequest mr1 = new MedicationRequest(); + mr1.addCategory().addCoding().setSystem("urn:medicationroute").setCode("oral"); + mr1.addDosageInstruction().getTiming().addEventElement().setValueAsString("2017-01-01"); + myMedicationRequestDao.create(mr1, mySrd).getId().toUnqualifiedVersionless(); + + MedicationRequest mr2 = new MedicationRequest(); + mr2.addCategory().addCoding().setSystem("urn:medicationroute").setCode("oral"); + IIdType id2 = myMedicationRequestDao.create(mr2, mySrd).getId().toUnqualifiedVersionless(); + + SearchParameterMap map = new SearchParameterMap(); + map.add(MedicationRequest.SP_DATE, new DateParam().setMissing(true)); + IBundleProvider results = myMedicationRequestDao.search(map, mySrd); + List ids = toUnqualifiedVersionlessIdValues(results); + + assertThat(ids).containsExactly(id2.getValue()); + + } + + @Test + public void testSearchWithMissingQuantity() { + IIdType notMissing; + IIdType missing; + { + Observation obs = new Observation(); + obs.addIdentifier().setSystem("urn:system").setValue("001"); + missing = myObservationDao.create(obs, mySrd).getId().toUnqualifiedVersionless(); + } + { + Observation obs = new Observation(); + obs.addIdentifier().setSystem("urn:system").setValue("002"); + obs.setValue(new Quantity(123)); + notMissing = myObservationDao.create(obs, mySrd).getId().toUnqualifiedVersionless(); + } + // Quantity Param + { + SearchParameterMap params = new SearchParameterMap(); + params.setLoadSynchronous(true); + QuantityParam param = new QuantityParam(); + param.setMissing(false); + params.add(Observation.SP_VALUE_QUANTITY, param); + List patients = toUnqualifiedVersionlessIds(myObservationDao.search(params, mySrd)); + assertThat(patients).doesNotContainSubsequence(missing); + assertThat(patients).containsSubsequence(notMissing); + } + { + SearchParameterMap params = new SearchParameterMap(); + params.setLoadSynchronous(true); + QuantityParam param = new QuantityParam(); + param.setMissing(true); + params.add(Observation.SP_VALUE_QUANTITY, param); + List patients = toUnqualifiedVersionlessIds(myObservationDao.search(params, mySrd)); + assertThat(patients).containsSubsequence(missing); + assertThat(patients).doesNotContainSubsequence(notMissing); + } + } + + @Test + public void testSearchWithMissingQuantityWithNormalizedQuantitySearchSupported() { + + myStorageSettings.setNormalizedQuantitySearchLevel(NormalizedQuantitySearchLevel.NORMALIZED_QUANTITY_SEARCH_SUPPORTED); + IIdType notMissing; + IIdType missing; + { + Observation obs = new Observation(); + obs.addIdentifier().setSystem("urn:system").setValue("001"); + missing = myObservationDao.create(obs, mySrd).getId().toUnqualifiedVersionless(); + } + { + Observation obs = new Observation(); + obs.addIdentifier().setSystem("urn:system").setValue("002"); + obs.setValue(new Quantity(123)); + notMissing = myObservationDao.create(obs, mySrd).getId().toUnqualifiedVersionless(); + } + + runInTransaction(() -> { + ourLog.info("Quantity Indexes:\n * {}", + myResourceIndexedSearchParamQuantityDao.findAll().stream() + .filter(t -> t.getParamName().equals("value-quantity")).map(ResourceIndexedSearchParamQuantity::toString).collect(Collectors.joining("\n * ") + ) + ); + ourLog.info("Normalized Quantity Indexes:\n * {}", + myResourceIndexedSearchParamQuantityNormalizedDao.findAll().stream(). + filter(t -> t.getParamName().equals("value-quantity")).map(ResourceIndexedSearchParamQuantityNormalized::toString).collect(Collectors.joining("\n * ") + ) + ); + }); + + // Quantity Param + { + SearchParameterMap params = new SearchParameterMap(); + params.setLoadSynchronous(true); + QuantityParam param = new QuantityParam(); + param.setMissing(false); + params.add(Observation.SP_VALUE_QUANTITY, param); + List patients = toUnqualifiedVersionlessIds(myObservationDao.search(params, mySrd)); + assertThat(patients).doesNotContainSubsequence(missing); + assertThat(patients).containsSubsequence(notMissing); + } + { + SearchParameterMap params = new SearchParameterMap(); + params.setLoadSynchronous(true); + QuantityParam param = new QuantityParam(); + param.setMissing(true); + params.add(Observation.SP_VALUE_QUANTITY, param); + myCaptureQueriesListener.clear(); + List patients = toUnqualifiedVersionlessIds(myObservationDao.search(params, mySrd)); + myCaptureQueriesListener.logSelectQueries(); + assertThat(patients).containsSubsequence(missing); + assertThat(patients).doesNotContainSubsequence(notMissing); + } + + } + + @Test + public void testSearchWithMissingQuantityWithNormalizedQuantityStorageSupported() { + + myStorageSettings.setNormalizedQuantitySearchLevel(NormalizedQuantitySearchLevel.NORMALIZED_QUANTITY_STORAGE_SUPPORTED); + IIdType notMissing; + IIdType missing; + { + Observation obs = new Observation(); + obs.addIdentifier().setSystem("urn:system").setValue("001"); + missing = myObservationDao.create(obs, mySrd).getId().toUnqualifiedVersionless(); + } + { + Observation obs = new Observation(); + obs.addIdentifier().setSystem("urn:system").setValue("002"); + obs.setValue(new Quantity(123)); + notMissing = myObservationDao.create(obs, mySrd).getId().toUnqualifiedVersionless(); + } + // Quantity Param + { + SearchParameterMap params = new SearchParameterMap(); + params.setLoadSynchronous(true); + QuantityParam param = new QuantityParam(); + param.setMissing(false); + params.add(Observation.SP_VALUE_QUANTITY, param); + List patients = toUnqualifiedVersionlessIds(myObservationDao.search(params, mySrd)); + assertThat(patients).doesNotContainSubsequence(missing); + assertThat(patients).containsSubsequence(notMissing); + } + { + SearchParameterMap params = new SearchParameterMap(); + params.setLoadSynchronous(true); + QuantityParam param = new QuantityParam(); + param.setMissing(true); + params.add(Observation.SP_VALUE_QUANTITY, param); + List patients = toUnqualifiedVersionlessIds(myObservationDao.search(params, mySrd)); + assertThat(patients).containsSubsequence(missing); + assertThat(patients).doesNotContainSubsequence(notMissing); + } + + } + + + @Test + public void testSearchWithMissingReference() { + IIdType orgId = myOrganizationDao.create(new Organization(), mySrd).getId().toUnqualifiedVersionless(); + IIdType notMissing; + IIdType missing; + { + Patient patient = new Patient(); + patient.addIdentifier().setSystem("urn:system").setValue("001"); + missing = myPatientDao.create(patient, mySrd).getId().toUnqualifiedVersionless(); + } + { + Patient patient = new Patient(); + patient.addIdentifier().setSystem("urn:system").setValue("002"); + patient.addName().setFamily("Tester_testSearchStringParam").addGiven("John"); + patient.setBirthDateElement(new DateType("2011-01-01")); + patient.getManagingOrganization().setReferenceElement(orgId); + notMissing = myPatientDao.create(patient, mySrd).getId().toUnqualifiedVersionless(); + } + // Reference Param + { + SearchParameterMap params = new SearchParameterMap(); + params.setLoadSynchronous(true); + ReferenceParam param = new ReferenceParam(); + param.setMissing(false); + params.add(Patient.SP_ORGANIZATION, param); + List patients = toUnqualifiedVersionlessIds(myPatientDao.search(params, mySrd)); + assertThat(patients).doesNotContainSubsequence(missing); + assertThat(patients).containsSubsequence(notMissing); + } + { + SearchParameterMap params = new SearchParameterMap(); + params.setLoadSynchronous(true); + ReferenceParam param = new ReferenceParam(); + param.setMissing(true); + params.add(Patient.SP_ORGANIZATION, param); + List patients = toUnqualifiedVersionlessIds(myPatientDao.search(params, mySrd)); + assertThat(patients).containsSubsequence(missing); + assertThat(patients).doesNotContainSubsequence(notMissing); + assertThat(patients).doesNotContainSubsequence(orgId); + } + } + + + @Test + public void testSearchWithMissingReference_resourceTypeWithMultipleReferences() { + IIdType patientId = createPatient(); + IIdType observationId = createObservation(withSubject(patientId)); - @Test - public void testSearchWithMissingReference() { - IIdType orgId = myOrganizationDao.create(new Organization(), mySrd).getId().toUnqualifiedVersionless(); - IIdType notMissing; - IIdType missing; - { - Patient patient = new Patient(); - patient.addIdentifier().setSystem("urn:system").setValue("001"); - missing = myPatientDao.create(patient, mySrd).getId().toUnqualifiedVersionless(); - } - { - Patient patient = new Patient(); - patient.addIdentifier().setSystem("urn:system").setValue("002"); - patient.addName().setFamily("Tester_testSearchStringParam").addGiven("John"); - patient.setBirthDateElement(new DateType("2011-01-01")); - patient.getManagingOrganization().setReferenceElement(orgId); - notMissing = myPatientDao.create(patient, mySrd).getId().toUnqualifiedVersionless(); - } - // Reference Param - { SearchParameterMap params = new SearchParameterMap(); - params.setLoadSynchronous(true); - ReferenceParam param = new ReferenceParam(); - param.setMissing(false); - params.add(Patient.SP_ORGANIZATION, param); - List patients = toUnqualifiedVersionlessIds(myPatientDao.search(params)); - assertThat(patients).doesNotContainSubsequence(missing); - assertThat(patients).containsSubsequence(notMissing); + params.add(Observation.SP_PERFORMER, new ReferenceParam().setMissing(true)); + IBundleProvider bundleProvider = myObservationDao.search(params, mySrd); + assertThat(bundleProvider.getAllResourceIds()).containsExactly(observationId.getIdPart()); } - { - SearchParameterMap params = new SearchParameterMap(); - params.setLoadSynchronous(true); - ReferenceParam param = new ReferenceParam(); - param.setMissing(true); - params.add(Patient.SP_ORGANIZATION, param); - List patients = toUnqualifiedVersionlessIds(myPatientDao.search(params)); - assertThat(patients).containsSubsequence(missing); - assertThat(patients).doesNotContainSubsequence(notMissing); - assertThat(patients).doesNotContainSubsequence(orgId); - } - } - @Test - public void testSearchWithMissingString() { - IIdType orgId = myOrganizationDao.create(new Organization(), mySrd).getId(); - IIdType notMissing; - IIdType missing; - { - Patient patient = new Patient(); - patient.addIdentifier().setSystem("urn:system").setValue("001"); - missing = myPatientDao.create(patient, mySrd).getId().toUnqualifiedVersionless(); - } - { - Patient patient = new Patient(); - patient.addIdentifier().setSystem("urn:system").setValue("002"); - patient.addName().setFamily("Tester_testSearchStringParam").addGiven("John"); - patient.setBirthDateElement(new DateType("2011-01-01")); - patient.getManagingOrganization().setReferenceElement(orgId); - notMissing = myPatientDao.create(patient, mySrd).getId().toUnqualifiedVersionless(); - } - // String Param - { - SearchParameterMap params = new SearchParameterMap(); - params.setLoadSynchronous(true); - StringParam param = new StringParam(); - param.setMissing(false); - params.add(Patient.SP_FAMILY, param); - List patients = toUnqualifiedVersionlessIds(myPatientDao.search(params)); - assertThat(patients).doesNotContainSubsequence(missing); - assertThat(patients).containsSubsequence(notMissing); - } - { - SearchParameterMap params = new SearchParameterMap(); - params.setLoadSynchronous(true); - StringParam param = new StringParam(); - param.setMissing(true); - params.add(Patient.SP_FAMILY, param); - List patients = toUnqualifiedVersionlessIds(myPatientDao.search(params)); - assertThat(patients).containsSubsequence(missing); - assertThat(patients).doesNotContainSubsequence(notMissing); - } - } + @Test + public void testSearchWithMissingReference_searchParamMultiplePaths() { + IIdType encounterId = createEncounter(); + createObservation(withEncounter(encounterId.getValue())); - @Test - public void testSearchWithToken() { - IIdType notMissing; - IIdType missing; - { - Observation obs = new Observation(); - obs.addIdentifier().setSystem("urn:system").setValue("001"); - missing = myObservationDao.create(obs, mySrd).getId().toUnqualifiedVersionless(); - } - { - Observation obs = new Observation(); - obs.addIdentifier().setSystem("urn:system").setValue("002"); - obs.getCode().addCoding().setSystem("urn:system").setCode("002"); - notMissing = myObservationDao.create(obs, mySrd).getId().toUnqualifiedVersionless(); - } - // Token Param - { - SearchParameterMap params = new SearchParameterMap(); - params.setLoadSynchronous(true); - TokenParam param = new TokenParam(); - param.setMissing(false); - params.add(Observation.SP_CODE, param); - List patients = toUnqualifiedVersionlessIds(myObservationDao.search(params)); - assertThat(patients).doesNotContainSubsequence(missing); - assertThat(patients).containsSubsequence(notMissing); - } - { SearchParameterMap params = new SearchParameterMap(); - params.setLoadSynchronous(true); - TokenParam param = new TokenParam(); - param.setMissing(true); - params.add(Observation.SP_CODE, param); - List patients = toUnqualifiedVersionlessIds(myObservationDao.search(params)); - assertThat(patients).containsSubsequence(missing); - assertThat(patients).doesNotContainSubsequence(notMissing); + params.add(Observation.SP_ENCOUNTER, new ReferenceParam().setMissing(true)); + IBundleProvider bundleProvider = myObservationDao.search(params, mySrd); + assertThat(bundleProvider.getAllResourceIds()).isEmpty(); + } + + @Test + public void testSearchWithMissingString() { + IIdType orgId = myOrganizationDao.create(new Organization(), mySrd).getId(); + IIdType notMissing; + IIdType missing; + { + Patient patient = new Patient(); + patient.addIdentifier().setSystem("urn:system").setValue("001"); + missing = myPatientDao.create(patient, mySrd).getId().toUnqualifiedVersionless(); + } + { + Patient patient = new Patient(); + patient.addIdentifier().setSystem("urn:system").setValue("002"); + patient.addName().setFamily("Tester_testSearchStringParam").addGiven("John"); + patient.setBirthDateElement(new DateType("2011-01-01")); + patient.getManagingOrganization().setReferenceElement(orgId); + notMissing = myPatientDao.create(patient, mySrd).getId().toUnqualifiedVersionless(); + } + // String Param + { + SearchParameterMap params = new SearchParameterMap(); + params.setLoadSynchronous(true); + StringParam param = new StringParam(); + param.setMissing(false); + params.add(Patient.SP_FAMILY, param); + List patients = toUnqualifiedVersionlessIds(myPatientDao.search(params, mySrd)); + assertThat(patients).doesNotContainSubsequence(missing); + assertThat(patients).containsSubsequence(notMissing); + } + { + SearchParameterMap params = new SearchParameterMap(); + params.setLoadSynchronous(true); + StringParam param = new StringParam(); + param.setMissing(true); + params.add(Patient.SP_FAMILY, param); + List patients = toUnqualifiedVersionlessIds(myPatientDao.search(params, mySrd)); + assertThat(patients).containsSubsequence(missing); + assertThat(patients).doesNotContainSubsequence(notMissing); + } + } + + @Test + public void testSearchWithToken() { + IIdType notMissing; + IIdType missing; + { + Observation obs = new Observation(); + obs.addIdentifier().setSystem("urn:system").setValue("001"); + missing = myObservationDao.create(obs, mySrd).getId().toUnqualifiedVersionless(); + } + { + Observation obs = new Observation(); + obs.addIdentifier().setSystem("urn:system").setValue("002"); + obs.getCode().addCoding().setSystem("urn:system").setCode("002"); + notMissing = myObservationDao.create(obs, mySrd).getId().toUnqualifiedVersionless(); + } + // Token Param + { + SearchParameterMap params = new SearchParameterMap(); + params.setLoadSynchronous(true); + TokenParam param = new TokenParam(); + param.setMissing(false); + params.add(Observation.SP_CODE, param); + List patients = toUnqualifiedVersionlessIds(myObservationDao.search(params, mySrd)); + assertThat(patients).doesNotContainSubsequence(missing); + assertThat(patients).containsSubsequence(notMissing); + } + { + SearchParameterMap params = new SearchParameterMap(); + params.setLoadSynchronous(true); + TokenParam param = new TokenParam(); + param.setMissing(true); + params.add(Observation.SP_CODE, param); + List patients = toUnqualifiedVersionlessIds(myObservationDao.search(params, mySrd)); + assertThat(patients).containsSubsequence(missing); + assertThat(patients).doesNotContainSubsequence(notMissing); + } } } diff --git a/hapi-fhir-jpaserver-test-r4/src/test/java/ca/uhn/fhir/jpa/provider/r4/ResourceProviderR4Test.java b/hapi-fhir-jpaserver-test-r4/src/test/java/ca/uhn/fhir/jpa/provider/r4/ResourceProviderR4Test.java index cb098dc7012..427970449c6 100644 --- a/hapi-fhir-jpaserver-test-r4/src/test/java/ca/uhn/fhir/jpa/provider/r4/ResourceProviderR4Test.java +++ b/hapi-fhir-jpaserver-test-r4/src/test/java/ca/uhn/fhir/jpa/provider/r4/ResourceProviderR4Test.java @@ -217,7 +217,7 @@ public class ResourceProviderR4Test extends BaseResourceProviderR4Test { private static final org.slf4j.Logger ourLog = org.slf4j.LoggerFactory.getLogger(ResourceProviderR4Test.class); private SearchCoordinatorSvcImpl mySearchCoordinatorSvcRaw; - private CapturingInterceptor myCapturingInterceptor = new CapturingInterceptor(); + private final CapturingInterceptor myCapturingInterceptor = new CapturingInterceptor(); @Autowired private ISearchDao mySearchEntityDao; @@ -413,15 +413,15 @@ public void testSearchWithContainsLowerCase() { Patient pt1 = new Patient(); pt1.addName().setFamily("Elizabeth"); - String pt1id = myPatientDao.create(pt1).getId().toUnqualifiedVersionless().getValue(); + String pt1id = myPatientDao.create(pt1, mySrd).getId().toUnqualifiedVersionless().getValue(); Patient pt2 = new Patient(); pt2.addName().setFamily("fghijk"); - String pt2id = myPatientDao.create(pt2).getId().toUnqualifiedVersionless().getValue(); + String pt2id = myPatientDao.create(pt2, mySrd).getId().toUnqualifiedVersionless().getValue(); Patient pt3 = new Patient(); pt3.addName().setFamily("zzzzz"); - myPatientDao.create(pt3).getId().toUnqualifiedVersionless().getValue(); + myPatientDao.create(pt3, mySrd).getId().toUnqualifiedVersionless().getValue(); Bundle output = myClient @@ -450,7 +450,7 @@ public void testSearchWithPercentSign() { Patient pt1 = new Patient(); pt1.addName().setFamily("Smith%"); - String pt1id = myPatientDao.create(pt1).getId().toUnqualifiedVersionless().getValue(); + String pt1id = myPatientDao.create(pt1, mySrd).getId().toUnqualifiedVersionless().getValue(); Bundle output = myClient .search() @@ -463,7 +463,7 @@ public void testSearchWithPercentSign() { Patient pt2 = new Patient(); pt2.addName().setFamily("Sm%ith"); - String pt2id = myPatientDao.create(pt2).getId().toUnqualifiedVersionless().getValue(); + String pt2id = myPatientDao.create(pt2, mySrd).getId().toUnqualifiedVersionless().getValue(); output = myClient .search() @@ -740,7 +740,7 @@ public void testDeleteConditional() { Patient p = new Patient(); p.addName().setFamily("FAM").addGiven("GIV"); - IIdType id = myPatientDao.create(p).getId(); + IIdType id = myPatientDao.create(p, mySrd).getId(); myClient.read().resource("Patient").withId(id.toUnqualifiedVersionless()).execute(); @@ -763,7 +763,7 @@ public void testResourceGoneIncludesVersion() { Patient p = new Patient(); p.addName().setFamily("FAM").addGiven("GIV"); - IIdType id = myPatientDao.create(p).getId().toUnqualifiedVersionless(); + IIdType id = myPatientDao.create(p, mySrd).getId().toUnqualifiedVersionless(); myClient .delete() @@ -1025,57 +1025,58 @@ public void testCodeSearch() { public void testCreateAndReadBackResourceWithContainedReferenceToContainer() { myFhirContext.setParserErrorHandler(new StrictErrorHandler()); - String input = "{\n" + - " \"resourceType\": \"Organization\",\n" + - " \"id\": \"1\",\n" + - " \"meta\": {\n" + - " \"tag\": [\n" + - " {\n" + - " \"system\": \"https://blah.org/deployment\",\n" + - " \"code\": \"e69414dd-b5c2-462d-bcfd-9d04d6b16596\",\n" + - " \"display\": \"DEPLOYMENT\"\n" + - " },\n" + - " {\n" + - " \"system\": \"https://blah.org/region\",\n" + - " \"code\": \"b47d7a5b-b159-4bed-a8f8-3258e6603adb\",\n" + - " \"display\": \"REGION\"\n" + - " },\n" + - " {\n" + - " \"system\": \"https://blah.org/provider\",\n" + - " \"code\": \"28c30004-0333-40cf-9e7f-3f9e080930bd\",\n" + - " \"display\": \"PROVIDER\"\n" + - " }\n" + - " ]\n" + - " },\n" + - " \"contained\": [\n" + - " {\n" + - " \"resourceType\": \"Location\",\n" + - " \"id\": \"2\",\n" + - " \"position\": {\n" + - " \"longitude\": 51.443238301454289,\n" + - " \"latitude\": 7.34196905697293\n" + - " },\n" + - " \"managingOrganization\": {\n" + - " \"reference\": \"#\"\n" + - " }\n" + - " }\n" + - " ],\n" + - " \"type\": [\n" + - " {\n" + - " \"coding\": [\n" + - " {\n" + - " \"system\": \"https://blah.org/fmc/OrganizationType\",\n" + - " \"code\": \"CLINIC\",\n" + - " \"display\": \"Clinic\"\n" + - " }\n" + - " ]\n" + - " }\n" + - " ],\n" + - " \"name\": \"testOrg\"\n" + - "}"; + String input = """ +{ + "resourceType": "Organization", + "id": "1", + "meta": { + "tag": [ + { + "system": "https://blah.org/deployment", + "code": "e69414dd-b5c2-462d-bcfd-9d04d6b16596", + "display": "DEPLOYMENT" + }, + { + "system": "https://blah.org/region", + "code": "b47d7a5b-b159-4bed-a8f8-3258e6603adb", + "display": "REGION" + }, + { + "system": "https://blah.org/provider", + "code": "28c30004-0333-40cf-9e7f-3f9e080930bd", + "display": "PROVIDER" + } + ] + }, + "contained": [ + { + "resourceType": "Location", + "id": "2", + "position": { + "longitude": 51.443238301454289, + "latitude": 7.34196905697293 + }, + "managingOrganization": { + "reference": "#" + } + } + ], + "type": [ + { + "coding": [ + { + "system": "https://blah.org/fmc/OrganizationType", + "code": "CLINIC", + "display": "Clinic" + } + ] + } + ], + "name": "testOrg" +}"""; Organization org = myFhirContext.newJsonParser().parseResource(Organization.class, input); - IIdType id = myOrganizationDao.create(org).getId(); + IIdType id = myOrganizationDao.create(org, mySrd).getId(); org = myOrganizationDao.read(id); String output = myFhirContext.newJsonParser().setPrettyPrint(true).encodeResourceToString(org); @@ -1095,9 +1096,7 @@ public void testCountParam() { } List outcome = myClient.transaction().withResources(resources).prettyPrint().encodedXml().execute(); - runInTransaction(() -> { - assertEquals(100, myResourceTableDao.count()); - }); + runInTransaction(() -> assertEquals(100, myResourceTableDao.count())); Bundle found = myClient .search() @@ -1306,7 +1305,7 @@ public void interceptResponse(IHttpResponse theResponse) { // TODO } @Test - public void testCreateQuestionnaireResponseWithValidation() throws IOException { + public void testCreateQuestionnaireResponseWithValidation() { CodeSystem cs = new CodeSystem(); cs.setUrl("http://cs"); cs.setStatus(Enumerations.PublicationStatus.ACTIVE); @@ -1906,8 +1905,8 @@ public void testDeleteResourceConditional2() throws Exception { * Try it with a raw socket call. The Apache client won't let us use the unescaped "|" in the URL but we want to make sure that works too.. */ Socket sock = new Socket(); - sock.setSoTimeout(3000); - try { + try (sock) { + sock.setSoTimeout(3000); sock.connect(new InetSocketAddress("localhost", myPort)); sock.getOutputStream().write(("DELETE /fhir/context/Patient?identifier=http://ghh.org/patient|" + methodName + " HTTP/1.1\n").getBytes(StandardCharsets.UTF_8)); sock.getOutputStream().write("Host: localhost\n".getBytes(StandardCharsets.UTF_8)); @@ -1915,7 +1914,6 @@ public void testDeleteResourceConditional2() throws Exception { BufferedReader socketInput = new BufferedReader(new InputStreamReader(sock.getInputStream())); - // String response = ""; StringBuilder b = new StringBuilder(); char[] buf = new char[1000]; while (socketInput.read(buf) != -1) { @@ -1925,9 +1923,7 @@ public void testDeleteResourceConditional2() throws Exception { ourLog.debug("Resp: {}", resp); } catch (SocketTimeoutException e) { - e.printStackTrace(); - } finally { - sock.close(); + ourLog.debug(e.getMessage(), e); } Thread.sleep(1000); @@ -2398,7 +2394,7 @@ public void testHistoryWithAtParameter() throws Exception { assertThat(idValues).as(idValues.toString()).hasSize(10); idValues = searchAndReturnUnqualifiedIdValues(myServerBase + "/_history?_at=gt" + InstantDt.withCurrentTime().getYear()); - assertThat(idValues).hasSize(0); + assertThat(idValues).isEmpty(); } @@ -2427,7 +2423,7 @@ public void testHistoryOnInstanceWithServerGeneratedId(boolean theInvalidateCach myMemoryCacheService.invalidateCaches(MemoryCacheService.CacheEnum.PID_TO_FORCED_ID); } - Bundle history = myClient.history().onInstance(id.getValue()).andReturnBundle(Bundle.class).execute(); + Bundle history = myClient.history().onInstance(id.getValue()).returnBundle(Bundle.class).execute(); assertEquals(1, history.getEntry().size()); BundleEntryComponent historyEntry0 = history.getEntry().get(0); // validate entry.fullUrl @@ -2476,7 +2472,7 @@ public void testHistoryOnInstanceWithForcedId(boolean theInvalidateCacheBeforeHi myMemoryCacheService.invalidateCaches(MemoryCacheService.CacheEnum.PID_TO_FORCED_ID); } - Bundle history = myClient.history().onInstance(id.getValue()).andReturnBundle(Bundle.class).execute(); + Bundle history = myClient.history().onInstance(id.getValue()).returnBundle(Bundle.class).execute(); assertEquals(1, history.getEntry().size()); BundleEntryComponent historyEntry0 = history.getEntry().get(0); // validate entry.fullUrl @@ -2508,7 +2504,7 @@ public void testHistoryWithDeletedResource() { ourLog.info("Res ID: {}", id); - Bundle history = myClient.history().onInstance(id.getValue()).andReturnBundle(Bundle.class).prettyPrint().summaryMode(SummaryEnum.DATA).execute(); + Bundle history = myClient.history().onInstance(id.getValue()).returnBundle(Bundle.class).prettyPrint().summaryMode(SummaryEnum.DATA).execute(); assertThat(history.getEntry()).hasSize(3); assertEquals(id.withVersion("3").getValue(), history.getEntry().get(0).getResource().getId()); assertThat(((Patient) history.getEntry().get(0).getResource()).getName()).hasSize(1); @@ -2746,7 +2742,7 @@ public void testPagingWithIncludesOnEachResource() { int total = 20; Organization org = new Organization(); org.setName("ORG"); - IIdType orgId = myOrganizationDao.create(org).getId().toUnqualifiedVersionless(); + IIdType orgId = myOrganizationDao.create(org, mySrd).getId().toUnqualifiedVersionless(); Coding tagCode = new Coding(); tagCode.setCode("test"); @@ -2757,7 +2753,7 @@ public void testPagingWithIncludesOnEachResource() { .addTag(tagCode); t.setStatus(Task.TaskStatus.REQUESTED); t.getOwner().setReference(orgId.getValue()); - myTaskDao.create(t); + myTaskDao.create(t, mySrd); } HashSet ids = new HashSet<>(); @@ -2835,12 +2831,12 @@ public void testPagingWithIncludesReturnsConsistentValues( if (orgCount > 0) { Organization org = new Organization(); org.setName("ORG"); - IIdType orgId = myOrganizationDao.create(org).getId().toUnqualifiedVersionless(); + IIdType orgId = myOrganizationDao.create(org, mySrd).getId().toUnqualifiedVersionless(); orgCount--; t.getOwner().setReference(orgId.getValue()); } - myTaskDao.create(t); + myTaskDao.create(t, mySrd); } } @@ -2909,12 +2905,12 @@ public void testPagingWithIncludesReturnsConsistentValues() { if (orgCount > 0) { Organization org = new Organization(); org.setName("ORG"); - IIdType orgId = myOrganizationDao.create(org).getId().toUnqualifiedVersionless(); + IIdType orgId = myOrganizationDao.create(org, mySrd).getId().toUnqualifiedVersionless(); orgCount--; t.getOwner().setReference(orgId.getValue()); } - myTaskDao.create(t); + myTaskDao.create(t, mySrd); } } @@ -2961,13 +2957,13 @@ public void testPagingWithIncludesReturnsConsistentValues() { public void testIncludeCountDoesntIncludeIncludes() { Organization org = new Organization(); org.setName("ORG"); - IIdType orgId = myOrganizationDao.create(org).getId().toUnqualifiedVersionless(); + IIdType orgId = myOrganizationDao.create(org, mySrd).getId().toUnqualifiedVersionless(); for (int i = 0; i < 10; i++) { Patient pt = new Patient(); pt.getManagingOrganization().setReference(orgId.getValue()); pt.addName().setFamily("FAM" + i); - myPatientDao.create(pt); + myPatientDao.create(pt, mySrd); } Bundle bundle = myClient @@ -3168,7 +3164,7 @@ public void testPatchUsingJsonPatch() throws Exception { Patient newPt = myClient.read().resource(Patient.class).withId(pid1.getIdPart()).execute(); assertEquals("2", newPt.getIdElement().getVersionIdPart()); - assertEquals(false, newPt.getActive()); + assertFalse(newPt.getActive()); } @Test @@ -3196,7 +3192,7 @@ public void testPatchUsingJsonPatchWithContentionCheckBad() throws Exception { Patient newPt = myClient.read().resource(Patient.class).withId(pid1.getIdPart()).execute(); assertEquals("1", newPt.getIdElement().getVersionIdPart()); - assertEquals(true, newPt.getActive()); + assertTrue(newPt.getActive()); } @Test @@ -3226,7 +3222,7 @@ public void testPatchUsingJsonPatchWithContentionCheckGood() throws Exception { Patient newPt = myClient.read().resource(Patient.class).withId(pid1.getIdPart()).execute(); assertEquals("2", newPt.getIdElement().getVersionIdPart()); - assertEquals(false, newPt.getActive()); + assertFalse(newPt.getActive()); } @Test @@ -3255,7 +3251,7 @@ public void testPatchUsingXmlPatch() throws Exception { Patient newPt = myClient.read().resource(Patient.class).withId(pid1.getIdPart()).execute(); assertEquals("2", newPt.getIdElement().getVersionIdPart()); - assertEquals(false, newPt.getActive()); + assertFalse(newPt.getActive()); } @Test @@ -3323,12 +3319,12 @@ public void testReadAllInstancesOfType() { { Bundle returned = myClient.search().forResource(Patient.class).encodedXml().returnBundle(Bundle.class).execute(); - assertThat(returned.getEntry().size()).isGreaterThan(1); + assertThat(returned.getEntry()).hasSizeGreaterThan(1); assertEquals(BundleType.SEARCHSET, returned.getType()); } { Bundle returned = myClient.search().forResource(Patient.class).encodedJson().returnBundle(Bundle.class).execute(); - assertThat(returned.getEntry().size()).isGreaterThan(1); + assertThat(returned.getEntry()).hasSizeGreaterThan(1); } } @@ -3350,7 +3346,7 @@ protected void doInTransactionWithoutResult(TransactionStatus status) { } }); - Bundle bundle = myClient.history().onServer().andReturnBundle(Bundle.class).execute(); + Bundle bundle = myClient.history().onServer().returnBundle(Bundle.class).execute(); assertEquals(1, bundle.getTotal()); assertThat(bundle.getEntry()).hasSize(1); assertEquals(id2.getIdPart(), bundle.getEntry().get(0).getResource().getIdElement().getIdPart()); @@ -3507,15 +3503,6 @@ public void testTerminologyWithCompleteCs_Expand() throws Exception { assertThat(text).doesNotContain("\"B\""); assertThat(text).doesNotContain("\"B1\""); } - - -// HttpGet read = new HttpGet(ourServerBase + "/Observation?patient=P5000000302&_sort:desc=code&code:in=http://fkcfhir.org/fhir/vs/ccdacapddialysisorder"); -// try (CloseableHttpResponse response = ourHttpClient.execute(read)) { -// String text = IOUtils.toString(response.getEntity().getContent(), StandardCharsets.UTF_8); -// ourLog.info(text); -// assertEquals(Constants.STATUS_HTTP_200_OK, response.getStatusLine().getStatusCode()); -// assertThat(text).doesNotContain("\"text\",\"type\""); -// } } @Test @@ -3873,9 +3860,7 @@ public void testSearchByLastUpdated() throws Exception { p.addName().setFamily(methodName + "1"); IIdType pid1 = myClient.create().resource(p).execute().getId().toUnqualifiedVersionless(); - Thread.sleep(10); long time1 = System.currentTimeMillis(); - Thread.sleep(10); Patient p2 = new Patient(); p2.addName().setFamily(methodName + "2"); @@ -4064,9 +4049,6 @@ public void testSearchInvalidParam() throws Exception { public void testSearchLastUpdatedParamRp() throws InterruptedException { String methodName = "testSearchLastUpdatedParamRp"; - int sleep = 100; - Thread.sleep(sleep); - DateTimeType beforeAny = new DateTimeType(new Date(), TemporalPrecisionEnum.MILLI); IIdType id1a; { @@ -4083,9 +4065,7 @@ public void testSearchLastUpdatedParamRp() throws InterruptedException { id1b = myClient.create().resource(patient).execute().getId().toUnqualifiedVersionless(); } - Thread.sleep(1100); DateTimeType beforeR2 = new DateTimeType(new Date(), TemporalPrecisionEnum.MILLI); - Thread.sleep(1100); IIdType id2; { @@ -4249,13 +4229,12 @@ private void testSearchReturnsResults(String search) throws IOException { Bundle bundle = myFhirContext.newXmlParser().parseResource(Bundle.class, resp); matches = bundle.getEntry().size(); - assertThat(matches).isGreaterThan(0); + assertThat(matches).isPositive(); } @Test public void testSearchReturnsSearchDate() throws Exception { Date before = new Date(); - Thread.sleep(1); //@formatter:off Bundle found = myClient @@ -4266,7 +4245,6 @@ public void testSearchReturnsSearchDate() throws Exception { .execute(); //@formatter:on - Thread.sleep(1); Date after = new Date(); InstantType updated = found.getMeta().getLastUpdatedElement(); @@ -4300,7 +4278,7 @@ public void testSearchWithNormalizedQuantitySearchSupported() throws Exception { myObservationDao.create(obs, mySrd); - ourLog.debug("Observation: \n" + myFhirContext.newJsonParser().setPrettyPrint(true).encodeResourceToString(obs)); + ourLog.debug("Observation: {}", myFhirContext.newJsonParser().setPrettyPrint(true).encodeResourceToString(obs)); } { @@ -4313,7 +4291,7 @@ public void testSearchWithNormalizedQuantitySearchSupported() throws Exception { myObservationDao.create(obs, mySrd); - ourLog.debug("Observation: \n" + myFhirContext.newJsonParser().setPrettyPrint(true).encodeResourceToString(obs)); + ourLog.debug("Observation: {}", myFhirContext.newJsonParser().setPrettyPrint(true).encodeResourceToString(obs)); } { @@ -4326,7 +4304,7 @@ public void testSearchWithNormalizedQuantitySearchSupported() throws Exception { myObservationDao.create(obs, mySrd); - ourLog.debug("Observation: \n" + myFhirContext.newJsonParser().setPrettyPrint(true).encodeResourceToString(obs)); + ourLog.debug("Observation: {}", myFhirContext.newJsonParser().setPrettyPrint(true).encodeResourceToString(obs)); } { @@ -4339,24 +4317,24 @@ public void testSearchWithNormalizedQuantitySearchSupported() throws Exception { myObservationDao.create(obs, mySrd); - ourLog.debug("Observation: \n" + myFhirContext.newJsonParser().setPrettyPrint(true).encodeResourceToString(obs)); + ourLog.debug("Observation: {}", myFhirContext.newJsonParser().setPrettyPrint(true).encodeResourceToString(obs)); } // > 1m String uri = myServerBase + "/Observation?code-value-quantity=http://" + UrlUtil.escapeUrlParam("loinc.org|2345-7$gt1|http://unitsofmeasure.org|m"); - ourLog.info("uri = " + uri); + ourLog.info("uri = {}", uri); List ids = searchAndReturnUnqualifiedVersionlessIdValues(uri); assertThat(ids).hasSize(3); //>= 100cm uri = myServerBase + "/Observation?code-value-quantity=http://" + UrlUtil.escapeUrlParam("loinc.org|2345-7$gt100|http://unitsofmeasure.org|cm"); - ourLog.info("uri = " + uri); + ourLog.info("uri = {}", uri); ids = searchAndReturnUnqualifiedVersionlessIdValues(uri); assertThat(ids).hasSize(3); //>= 10dm uri = myServerBase + "/Observation?code-value-quantity=http://" + UrlUtil.escapeUrlParam("loinc.org|2345-7$gt10|http://unitsofmeasure.org|dm"); - ourLog.info("uri = " + uri); + ourLog.info("uri = {}", uri); ids = searchAndReturnUnqualifiedVersionlessIdValues(uri); assertThat(ids).hasSize(3); } @@ -4381,7 +4359,7 @@ public void testSearchWithNormalizedQuantitySearchSupported_CombineUCUMOrNonUCUM myObservationDao.create(obs, mySrd); - ourLog.debug("Observation: \n" + myFhirContext.newJsonParser().setPrettyPrint(true).encodeResourceToString(obs)); + ourLog.debug("Observation: {}", myFhirContext.newJsonParser().setPrettyPrint(true).encodeResourceToString(obs)); } { @@ -4392,7 +4370,7 @@ public void testSearchWithNormalizedQuantitySearchSupported_CombineUCUMOrNonUCUM myObservationDao.create(obs, mySrd); - ourLog.debug("Observation: \n" + myFhirContext.newJsonParser().setPrettyPrint(true).encodeResourceToString(obs)); + ourLog.debug("Observation: {}", myFhirContext.newJsonParser().setPrettyPrint(true).encodeResourceToString(obs)); } { @@ -4403,7 +4381,7 @@ public void testSearchWithNormalizedQuantitySearchSupported_CombineUCUMOrNonUCUM myObservationDao.create(obs, mySrd); - ourLog.debug("Observation: \n" + myFhirContext.newJsonParser().setPrettyPrint(true).encodeResourceToString(obs)); + ourLog.debug("Observation: {}", myFhirContext.newJsonParser().setPrettyPrint(true).encodeResourceToString(obs)); } { @@ -4414,7 +4392,7 @@ public void testSearchWithNormalizedQuantitySearchSupported_CombineUCUMOrNonUCUM myObservationDao.create(obs, mySrd); - ourLog.debug("Observation: \n" + myFhirContext.newJsonParser().setPrettyPrint(true).encodeResourceToString(obs)); + ourLog.debug("Observation: {}", myFhirContext.newJsonParser().setPrettyPrint(true).encodeResourceToString(obs)); } String uri; @@ -4451,7 +4429,7 @@ public void testSearchWithNormalizedQuantitySearchSupported_DegreeFahrenheit() { myObservationDao.create(obs, mySrd); - ourLog.debug("Observation: \n" + myFhirContext.newJsonParser().setPrettyPrint(true).encodeResourceToString(obs)); + ourLog.debug("Observation: {}", myFhirContext.newJsonParser().setPrettyPrint(true).encodeResourceToString(obs)); } { @@ -4462,7 +4440,7 @@ public void testSearchWithNormalizedQuantitySearchSupported_DegreeFahrenheit() { myObservationDao.create(obs, mySrd); - ourLog.debug("Observation: \n" + myFhirContext.newJsonParser().setPrettyPrint(true).encodeResourceToString(obs)); + ourLog.debug("Observation: {}", myFhirContext.newJsonParser().setPrettyPrint(true).encodeResourceToString(obs)); } { @@ -4474,7 +4452,7 @@ public void testSearchWithNormalizedQuantitySearchSupported_DegreeFahrenheit() { myObservationDao.create(obs, mySrd); - ourLog.debug("Observation: \n" + myFhirContext.newJsonParser().setPrettyPrint(true).encodeResourceToString(obs)); + ourLog.debug("Observation: {}", myFhirContext.newJsonParser().setPrettyPrint(true).encodeResourceToString(obs)); } myCaptureQueriesListener.clear(); @@ -4490,8 +4468,7 @@ public void testSearchWithNormalizedQuantitySearchSupported_DegreeFahrenheit() { //-- check use normalized quantity table to search String searchSql = myCaptureQueriesListener.getSelectQueries().get(0).getSql(true, true); - assertThat(searchSql).doesNotContain("HFJ_SPIDX_QUANTITY t0"); - assertThat(searchSql).contains("HFJ_SPIDX_QUANTITY_NRML"); + assertThat(searchSql).doesNotContain("HFJ_SPIDX_QUANTITY t0").contains("HFJ_SPIDX_QUANTITY_NRML"); } @Test @@ -5044,7 +5021,7 @@ public void testSearchWithCompositeSortWith_CodeValueQuantity() throws IOExcepti oid1 = myObservationDao.create(obs, mySrd).getId().toUnqualifiedVersionless(); - ourLog.debug("Observation: \n" + myFhirContext.newJsonParser().setPrettyPrint(true).encodeResourceToString(obs)); + ourLog.debug("Observation: {}", myFhirContext.newJsonParser().setPrettyPrint(true).encodeResourceToString(obs)); } { @@ -5056,7 +5033,7 @@ public void testSearchWithCompositeSortWith_CodeValueQuantity() throws IOExcepti oid2 = myObservationDao.create(obs, mySrd).getId().toUnqualifiedVersionless(); - ourLog.debug("Observation: \n" + myFhirContext.newJsonParser().setPrettyPrint(true).encodeResourceToString(obs)); + ourLog.debug("Observation: {}", myFhirContext.newJsonParser().setPrettyPrint(true).encodeResourceToString(obs)); } { @@ -5068,7 +5045,7 @@ public void testSearchWithCompositeSortWith_CodeValueQuantity() throws IOExcepti oid3 = myObservationDao.create(obs, mySrd).getId().toUnqualifiedVersionless(); - ourLog.debug("Observation: \n" + myFhirContext.newJsonParser().setPrettyPrint(true).encodeResourceToString(obs)); + ourLog.debug("Observation: {}", myFhirContext.newJsonParser().setPrettyPrint(true).encodeResourceToString(obs)); } { @@ -5080,7 +5057,7 @@ public void testSearchWithCompositeSortWith_CodeValueQuantity() throws IOExcepti oid4 = myObservationDao.create(obs, mySrd).getId().toUnqualifiedVersionless(); - ourLog.debug("Observation: \n" + myFhirContext.newJsonParser().setPrettyPrint(true).encodeResourceToString(obs)); + ourLog.debug("Observation: {}", myFhirContext.newJsonParser().setPrettyPrint(true).encodeResourceToString(obs)); } String uri = myServerBase + "/Observation?_sort=code-value-quantity"; @@ -5092,7 +5069,7 @@ public void testSearchWithCompositeSortWith_CodeValueQuantity() throws IOExcepti found = myFhirContext.newXmlParser().parseResource(Bundle.class, output); } - ourLog.debug("Bundle: \n" + myFhirContext.newJsonParser().setPrettyPrint(true).encodeResourceToString(found)); + ourLog.debug("Bundle: {}\n", myFhirContext.newJsonParser().setPrettyPrint(true).encodeResourceToString(found)); List list = toUnqualifiedVersionlessIds(found); assertThat(found.getEntry()).hasSize(4); @@ -5129,7 +5106,7 @@ public void testSearchWithCompositeSortWith_CompCodeValueQuantity() throws IOExc oid1 = myObservationDao.create(obs, mySrd).getId().toUnqualifiedVersionless(); - ourLog.debug("Observation: \n" + myFhirContext.newJsonParser().setPrettyPrint(true).encodeResourceToString(obs)); + ourLog.debug("Observation: {}", myFhirContext.newJsonParser().setPrettyPrint(true).encodeResourceToString(obs)); } { @@ -5145,7 +5122,7 @@ public void testSearchWithCompositeSortWith_CompCodeValueQuantity() throws IOExc oid2 = myObservationDao.create(obs, mySrd).getId().toUnqualifiedVersionless(); - ourLog.debug("Observation: \n" + myFhirContext.newJsonParser().setPrettyPrint(true).encodeResourceToString(obs)); + ourLog.debug("Observation: {}", myFhirContext.newJsonParser().setPrettyPrint(true).encodeResourceToString(obs)); } { @@ -5161,7 +5138,7 @@ public void testSearchWithCompositeSortWith_CompCodeValueQuantity() throws IOExc oid3 = myObservationDao.create(obs, mySrd).getId().toUnqualifiedVersionless(); - ourLog.debug("Observation: \n" + myFhirContext.newJsonParser().setPrettyPrint(true).encodeResourceToString(obs)); + ourLog.debug("Observation: {}", myFhirContext.newJsonParser().setPrettyPrint(true).encodeResourceToString(obs)); } { @@ -5176,7 +5153,7 @@ public void testSearchWithCompositeSortWith_CompCodeValueQuantity() throws IOExc comp.setValue(new Quantity().setValue(250)); oid4 = myObservationDao.create(obs, mySrd).getId().toUnqualifiedVersionless(); - ourLog.debug("Observation: \n" + myFhirContext.newJsonParser().setPrettyPrint(true).encodeResourceToString(obs)); + ourLog.debug("Observation: {}", myFhirContext.newJsonParser().setPrettyPrint(true).encodeResourceToString(obs)); } String uri = myServerBase + "/Observation?_sort=combo-code-value-quantity"; @@ -5188,7 +5165,7 @@ public void testSearchWithCompositeSortWith_CompCodeValueQuantity() throws IOExc found = myFhirContext.newXmlParser().parseResource(Bundle.class, output); } - ourLog.debug("Bundle: \n" + myFhirContext.newJsonParser().setPrettyPrint(true).encodeResourceToString(found)); + ourLog.debug("Bundle: {}\n", myFhirContext.newJsonParser().setPrettyPrint(true).encodeResourceToString(found)); List list = toUnqualifiedVersionlessIds(found); assertThat(found.getEntry()).hasSize(4); @@ -5264,9 +5241,7 @@ public void testSearchWithMissing() { List list = toUnqualifiedVersionlessIds(found); ourLog.info(methodName + " found: " + list.toString() + " - Wanted " + orgMissing + " but not " + orgNotMissing); - assertThat(list).doesNotContain(orgNotMissing); - assertThat(list).doesNotContain(deletedIdMissingTrue); - assertThat(list).contains(orgMissing); + assertThat(list).doesNotContain(orgNotMissing).doesNotContain(deletedIdMissingTrue).contains(orgMissing); } @Test @@ -5927,7 +5902,6 @@ public void testUpdateResourceWithPrefer() throws Exception { } Date before = new Date(); - Thread.sleep(100); pt = new Patient(); pt.setId(id.getIdPart()); @@ -6450,7 +6424,7 @@ public void testUpdateWithNormalizedQuantitySearchSupported() throws Exception { cc.addCoding().setCode("2345-7").setSystem("http://loinc.org"); obs.setValue(new Quantity().setValueElement(new DecimalType(125.12)).setUnit("CM").setSystem(UcumServiceUtil.UCUM_CODESYSTEM_URL).setCode("cm")); - ourLog.debug("Observation: \n" + myFhirContext.newJsonParser().setPrettyPrint(true).encodeResourceToString(obs)); + ourLog.debug("Observation: {}", myFhirContext.newJsonParser().setPrettyPrint(true).encodeResourceToString(obs)); IIdType opid1 = myObservationDao.create(obs, mySrd).getId(); @@ -6463,7 +6437,7 @@ public void testUpdateWithNormalizedQuantitySearchSupported() throws Exception { cc.addCoding().setCode("2345-7").setSystem("http://loinc.org"); obs.setValue(new Quantity().setValueElement(new DecimalType(24.12)).setUnit("CM").setSystem(UcumServiceUtil.UCUM_CODESYSTEM_URL).setCode("cm")); - ourLog.debug("Observation: \n" + myFhirContext.newJsonParser().setPrettyPrint(true).encodeResourceToString(obs)); + ourLog.debug("Observation: {}", myFhirContext.newJsonParser().setPrettyPrint(true).encodeResourceToString(obs)); myObservationDao.update(obs, mySrd); } @@ -6479,7 +6453,7 @@ public void testUpdateWithNormalizedQuantitySearchSupported() throws Exception { myObservationDao.create(obs, mySrd); - ourLog.debug("Observation: \n" + myFhirContext.newJsonParser().setPrettyPrint(true).encodeResourceToString(obs)); + ourLog.debug("Observation: {}", myFhirContext.newJsonParser().setPrettyPrint(true).encodeResourceToString(obs)); } { @@ -6492,7 +6466,7 @@ public void testUpdateWithNormalizedQuantitySearchSupported() throws Exception { myObservationDao.create(obs, mySrd); - ourLog.debug("Observation: \n" + myFhirContext.newJsonParser().setPrettyPrint(true).encodeResourceToString(obs)); + ourLog.debug("Observation: {}", myFhirContext.newJsonParser().setPrettyPrint(true).encodeResourceToString(obs)); } { @@ -6505,25 +6479,25 @@ public void testUpdateWithNormalizedQuantitySearchSupported() throws Exception { myObservationDao.create(obs, mySrd); - ourLog.debug("Observation: \n" + myFhirContext.newJsonParser().setPrettyPrint(true).encodeResourceToString(obs)); + ourLog.debug("Observation: {}", myFhirContext.newJsonParser().setPrettyPrint(true).encodeResourceToString(obs)); } // > 1m String uri = myServerBase + "/Observation?code-value-quantity=http://" + UrlUtil.escapeUrlParam("loinc.org|2345-7$gt1|http://unitsofmeasure.org|m"); - ourLog.info("uri = " + uri); + ourLog.info("uri = {}", uri); List ids = searchAndReturnUnqualifiedVersionlessIdValues(uri); assertThat(ids).hasSize(2); //>= 100cm uri = myServerBase + "/Observation?code-value-quantity=http://" + UrlUtil.escapeUrlParam("loinc.org|2345-7$gt100|http://unitsofmeasure.org|cm"); - ourLog.info("uri = " + uri); + ourLog.info("uri = {}", uri); ids = searchAndReturnUnqualifiedVersionlessIdValues(uri); assertThat(ids).hasSize(2); //>= 10dm uri = myServerBase + "/Observation?code-value-quantity=http://" + UrlUtil.escapeUrlParam("loinc.org|2345-7$gt10|http://unitsofmeasure.org|dm"); - ourLog.info("uri = " + uri); + ourLog.info("uri = {}", uri); ids = searchAndReturnUnqualifiedVersionlessIdValues(uri); assertThat(ids).hasSize(2); } @@ -6540,7 +6514,7 @@ public void testSearchWithLowerBoundDate() throws Exception { patient.setBirthDateElement(new DateType("2073")); pid0 = myPatientDao.create(patient, mySrd).getId().toUnqualifiedVersionless(); - ourLog.debug("Patient: \n" + myFhirContext.newJsonParser().setPrettyPrint(true).encodeResourceToString(patient)); + ourLog.debug("Patient: {}\n", myFhirContext.newJsonParser().setPrettyPrint(true).encodeResourceToString(patient)); ourLog.info("pid0 " + pid0); } @@ -6553,7 +6527,7 @@ public void testSearchWithLowerBoundDate() throws Exception { String resp = IOUtils.toString(response.getEntity().getContent(), StandardCharsets.UTF_8); ourLog.info(resp); Bundle bundle = myFhirContext.newXmlParser().parseResource(Bundle.class, resp); - ourLog.debug("Patient: \n" + myFhirContext.newJsonParser().setPrettyPrint(true).encodeResourceToString(bundle)); + ourLog.debug("Patient: {}\n", myFhirContext.newJsonParser().setPrettyPrint(true).encodeResourceToString(bundle)); } uri = myServerBase + "/Patient?_total=accurate&birthdate=gt2072-01-01"; @@ -6564,7 +6538,7 @@ public void testSearchWithLowerBoundDate() throws Exception { String resp = IOUtils.toString(response.getEntity().getContent(), StandardCharsets.UTF_8); ourLog.info(resp); Bundle bundle = myFhirContext.newXmlParser().parseResource(Bundle.class, resp); - ourLog.debug("Patient: \n" + myFhirContext.newJsonParser().setPrettyPrint(true).encodeResourceToString(bundle)); + ourLog.debug("Patient: {}\n", myFhirContext.newJsonParser().setPrettyPrint(true).encodeResourceToString(bundle)); } } @@ -6995,9 +6969,7 @@ public void createResource_refIntegrityOnWriteAndRefTargetTypes_throws(CreateRes && theInput.IsEnforceRefOnType && theInput.IsEnforceRefOnWrite).isFalse(); } catch (InvalidRequestException ex) { - assertThat(ex.getMessage().contains( - "Invalid resource reference" - )).as(ex.getMessage()).isTrue(); + assertThat(ex.getMessage()).as(ex.getMessage()).contains("Invalid resource reference"); } finally { myStorageSettings.setEnforceReferentialIntegrityOnWrite(isEnforceRefOnWrite); myStorageSettings.setEnforceReferenceTargetTypes(isEnforceRefTargetTypes); @@ -7331,9 +7303,7 @@ public void testMissingDateParameter(MissingSearchTestParameters theParams) { patient.setBirthDate(cal.getTime()); } return patient; - }, (isMissing) -> { - return doSearch(Patient.class, Patient.BIRTHDATE.isMissing(isMissing)); - }); + }, (isMissing) -> doSearch(Patient.class, Patient.BIRTHDATE.isMissing(isMissing))); } @ParameterizedTest @@ -7346,9 +7316,7 @@ public void testMissingTokenClientParameter(MissingSearchTestParameters theParam patient.setGender(AdministrativeGender.FEMALE); } return patient; - }, isMissing -> { - return doSearch(Patient.class, Patient.GENDER.isMissing(isMissing)); - }); + }, isMissing -> doSearch(Patient.class, Patient.GENDER.isMissing(isMissing))); } @ParameterizedTest @@ -7364,9 +7332,7 @@ public void testMissingReferenceClientParameter(MissingSearchTestParameters theP patient.setGeneralPractitioner(Collections.singletonList(new Reference(practitionerId))); } return patient; - }, isMissing -> { - return doSearch(Patient.class, Patient.GENERAL_PRACTITIONER.isMissing(isMissing)); - }); + }, isMissing -> doSearch(Patient.class, Patient.GENERAL_PRACTITIONER.isMissing(isMissing))); } @ParameterizedTest @@ -7409,9 +7375,7 @@ public void testMissingURLParameter(MissingSearchTestParameters theParams) { sp.setUrl("http://example.com"); } return sp; - }, isMissing -> { - return doSearch(SearchParameter.class, SearchParameter.URL.isMissing(isMissing)); - }); + }, isMissing -> doSearch(SearchParameter.class, SearchParameter.URL.isMissing(isMissing))); } @ParameterizedTest @@ -7424,9 +7388,7 @@ public void testMissingQuantityClientParameter(MissingSearchTestParameters thePa obs.setValue(new Quantity(3)); } return obs; - }, isMissing -> { - return doSearch(Observation.class, Observation.VALUE_QUANTITY.isMissing(isMissing)); - }); + }, isMissing -> doSearch(Observation.class, Observation.VALUE_QUANTITY.isMissing(isMissing))); } @ParameterizedTest @@ -7457,7 +7419,7 @@ private interface XtoY { Y doTask(X theInput); } - private static class MissingSearchTestParameters { + public static class MissingSearchTestParameters { /** * The setting for IndexMissingFields */