diff --git a/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/dao/BaseHapiFhirResourceDao.java b/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/dao/BaseHapiFhirResourceDao.java index fdae54c72fe..5fe0af073ff 100644 --- a/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/dao/BaseHapiFhirResourceDao.java +++ b/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/dao/BaseHapiFhirResourceDao.java @@ -632,7 +632,7 @@ public abstract class BaseHapiFhirResourceDao extends B } } - mySearchParamRegistry.forceRefresh(); + mySearchParamRegistry.requestRefresh(); } @Override diff --git a/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/dao/BaseSearchParamRegistry.java b/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/dao/BaseSearchParamRegistry.java index b936ea00a89..28107fcba94 100644 --- a/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/dao/BaseSearchParamRegistry.java +++ b/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/dao/BaseSearchParamRegistry.java @@ -61,12 +61,18 @@ public abstract class BaseSearchParamRegistry implemen } @Override - public void forceRefresh() { + public void requestRefresh() { synchronized (this) { myLastRefresh = 0; } } + @Override + public void forceRefresh() { + requestRefresh(); + refreshCacheIfNecessary(); + } + @Override public RuntimeSearchParam getActiveSearchParam(String theResourceName, String theParamName) { RuntimeSearchParam retVal = null; diff --git a/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/dao/ISearchParamRegistry.java b/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/dao/ISearchParamRegistry.java index 549112e69b7..72b89d670b7 100644 --- a/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/dao/ISearchParamRegistry.java +++ b/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/dao/ISearchParamRegistry.java @@ -29,6 +29,9 @@ import java.util.Set; public interface ISearchParamRegistry { + /** + * Request that the cache be refreshed now, in the current thread + */ void forceRefresh(); /** @@ -36,13 +39,18 @@ public interface ISearchParamRegistry { */ RuntimeSearchParam getActiveSearchParam(String theResourceName, String theParamName); - Map getActiveSearchParams(String theResourceName); - Map> getActiveSearchParams(); - List getActiveUniqueSearchParams(String theResourceName); + Map getActiveSearchParams(String theResourceName); List getActiveUniqueSearchParams(String theResourceName, Set theParamNames); + List getActiveUniqueSearchParams(String theResourceName); + void refreshCacheIfNecessary(); + + /** + * Request that the cache be refreshed at the next convenient time (in a different thread) + */ + void requestRefresh(); } diff --git a/hapi-fhir-jpaserver-base/src/test/java/ca/uhn/fhir/jpa/dao/BaseJpaTest.java b/hapi-fhir-jpaserver-base/src/test/java/ca/uhn/fhir/jpa/dao/BaseJpaTest.java index c8a7c35f75c..3c19c497fa7 100644 --- a/hapi-fhir-jpaserver-base/src/test/java/ca/uhn/fhir/jpa/dao/BaseJpaTest.java +++ b/hapi-fhir-jpaserver-base/src/test/java/ca/uhn/fhir/jpa/dao/BaseJpaTest.java @@ -34,7 +34,6 @@ import org.springframework.transaction.support.TransactionTemplate; import javax.persistence.EntityManager; import java.io.IOException; import java.io.InputStream; -import java.sql.SQLException; import java.util.*; import java.util.concurrent.Callable; diff --git a/hapi-fhir-jpaserver-base/src/test/java/ca/uhn/fhir/jpa/dao/dstu2/FhirResourceDaoDstu2SearchCustomSearchParamTest.java b/hapi-fhir-jpaserver-base/src/test/java/ca/uhn/fhir/jpa/dao/dstu2/FhirResourceDaoDstu2SearchCustomSearchParamTest.java index 6156b1e230e..55e0091c669 100644 --- a/hapi-fhir-jpaserver-base/src/test/java/ca/uhn/fhir/jpa/dao/dstu2/FhirResourceDaoDstu2SearchCustomSearchParamTest.java +++ b/hapi-fhir-jpaserver-base/src/test/java/ca/uhn/fhir/jpa/dao/dstu2/FhirResourceDaoDstu2SearchCustomSearchParamTest.java @@ -22,7 +22,6 @@ import org.junit.Before; import org.junit.Ignore; import org.junit.Test; import org.mockito.internal.util.collections.ListUtil; -import org.thymeleaf.util.ListUtils; import java.util.List; @@ -54,93 +53,6 @@ public class FhirResourceDaoDstu2SearchCustomSearchParamTest extends BaseJpaDstu } } - - - - @Test - public void testOverrideAndDisableBuiltInSearchParametersWithOverridingEnabled() { - myDaoConfig.setDefaultSearchParamsCanBeOverridden(true); - - SearchParameter memberSp = new SearchParameter(); - memberSp.setCode("member"); - memberSp.setBase(ResourceTypeEnum.GROUP); - memberSp.setType(SearchParamTypeEnum.REFERENCE); - memberSp.setXpath("Group.member.entity"); - memberSp.setXpathUsage(XPathUsageTypeEnum.NORMAL); - memberSp.setStatus(ConformanceResourceStatusEnum.RETIRED); - mySearchParameterDao.create(memberSp, mySrd); - - SearchParameter identifierSp = new SearchParameter(); - identifierSp.setCode("identifier"); - identifierSp.setBase(ResourceTypeEnum.GROUP); - identifierSp.setType(SearchParamTypeEnum.TOKEN); - identifierSp.setXpath("Group.identifier"); - identifierSp.setXpathUsage(XPathUsageTypeEnum.NORMAL); - identifierSp.setStatus(ConformanceResourceStatusEnum.RETIRED); - mySearchParameterDao.create(identifierSp, mySrd); - - mySearchParamRegsitry.forceRefresh(); - - Patient p = new Patient(); - p.addName().addGiven("G"); - IIdType pid = myPatientDao.create(p).getId().toUnqualifiedVersionless(); - - Group g = new Group(); - g.addIdentifier().setSystem("urn:foo").setValue("bar"); - g.addMember().getEntity().setReference(pid); - myGroupDao.create(g); - - assertThat(myResourceLinkDao.findAll(), empty()); - assertThat(ListUtil.filter(myResourceIndexedSearchParamTokenDao.findAll(), new ListUtil.Filter() { - @Override - public boolean isOut(ResourceIndexedSearchParamToken object) { - return !object.getResourceType().equals("Group") || object.isMissing(); - } - }), empty()); - } - - @Test - public void testOverrideAndDisableBuiltInSearchParametersWithOverridingDisabled() { - myDaoConfig.setDefaultSearchParamsCanBeOverridden(false); - - SearchParameter memberSp = new SearchParameter(); - memberSp.setCode("member"); - memberSp.setBase(ResourceTypeEnum.GROUP); - memberSp.setType(SearchParamTypeEnum.REFERENCE); - memberSp.setXpath("Group.member.entity"); - memberSp.setXpathUsage(XPathUsageTypeEnum.NORMAL); - memberSp.setStatus(ConformanceResourceStatusEnum.RETIRED); - mySearchParameterDao.create(memberSp, mySrd); - - SearchParameter identifierSp = new SearchParameter(); - identifierSp.setCode("identifier"); - identifierSp.setBase(ResourceTypeEnum.GROUP); - identifierSp.setType(SearchParamTypeEnum.TOKEN); - identifierSp.setXpath("Group.identifier"); - identifierSp.setXpathUsage(XPathUsageTypeEnum.NORMAL); - identifierSp.setStatus(ConformanceResourceStatusEnum.RETIRED); - mySearchParameterDao.create(identifierSp, mySrd); - - mySearchParamRegsitry.forceRefresh(); - - Patient p = new Patient(); - p.addName().addGiven("G"); - IIdType pid = myPatientDao.create(p).getId().toUnqualifiedVersionless(); - - Group g = new Group(); - g.addIdentifier().setSystem("urn:foo").setValue("bar"); - g.addMember().getEntity().setReference(pid); - myGroupDao.create(g); - - assertThat(myResourceLinkDao.findAll(), not(empty())); - assertThat(ListUtil.filter(myResourceIndexedSearchParamTokenDao.findAll(), new ListUtil.Filter() { - @Override - public boolean isOut(ResourceIndexedSearchParamToken object) { - return !object.getResourceType().equals("Group") || object.isMissing(); - } - }), not(empty())); - } - @Test public void testCreateInvalidParamInvalidResourceName() { SearchParameter fooSp = new SearchParameter(); @@ -228,7 +140,7 @@ public class FhirResourceDaoDstu2SearchCustomSearchParamTest extends BaseJpaDstu } @Test - public void testCustomReferenceParameter() throws Exception { + public void testCustomReferenceParameter() { SearchParameter sp = new SearchParameter(); sp.setBase(ResourceTypeEnum.PATIENT); sp.setCode("myDoctor"); @@ -238,6 +150,8 @@ public class FhirResourceDaoDstu2SearchCustomSearchParamTest extends BaseJpaDstu sp.setStatus(ConformanceResourceStatusEnum.ACTIVE); mySearchParameterDao.create(sp); + mySearchParamRegsitry.forceRefresh(); + Practitioner pract = new Practitioner(); pract.setId("A"); pract.getName().addFamily("PRACT"); @@ -316,6 +230,90 @@ public class FhirResourceDaoDstu2SearchCustomSearchParamTest extends BaseJpaDstu } + @Test + public void testOverrideAndDisableBuiltInSearchParametersWithOverridingDisabled() { + myDaoConfig.setDefaultSearchParamsCanBeOverridden(false); + + SearchParameter memberSp = new SearchParameter(); + memberSp.setCode("member"); + memberSp.setBase(ResourceTypeEnum.GROUP); + memberSp.setType(SearchParamTypeEnum.REFERENCE); + memberSp.setXpath("Group.member.entity"); + memberSp.setXpathUsage(XPathUsageTypeEnum.NORMAL); + memberSp.setStatus(ConformanceResourceStatusEnum.RETIRED); + mySearchParameterDao.create(memberSp, mySrd); + + SearchParameter identifierSp = new SearchParameter(); + identifierSp.setCode("identifier"); + identifierSp.setBase(ResourceTypeEnum.GROUP); + identifierSp.setType(SearchParamTypeEnum.TOKEN); + identifierSp.setXpath("Group.identifier"); + identifierSp.setXpathUsage(XPathUsageTypeEnum.NORMAL); + identifierSp.setStatus(ConformanceResourceStatusEnum.RETIRED); + mySearchParameterDao.create(identifierSp, mySrd); + + mySearchParamRegsitry.forceRefresh(); + + Patient p = new Patient(); + p.addName().addGiven("G"); + IIdType pid = myPatientDao.create(p).getId().toUnqualifiedVersionless(); + + Group g = new Group(); + g.addIdentifier().setSystem("urn:foo").setValue("bar"); + g.addMember().getEntity().setReference(pid); + myGroupDao.create(g); + + assertThat(myResourceLinkDao.findAll(), not(empty())); + assertThat(ListUtil.filter(myResourceIndexedSearchParamTokenDao.findAll(), new ListUtil.Filter() { + @Override + public boolean isOut(ResourceIndexedSearchParamToken object) { + return !object.getResourceType().equals("Group") || object.isMissing(); + } + }), not(empty())); + } + + @Test + public void testOverrideAndDisableBuiltInSearchParametersWithOverridingEnabled() { + myDaoConfig.setDefaultSearchParamsCanBeOverridden(true); + + SearchParameter memberSp = new SearchParameter(); + memberSp.setCode("member"); + memberSp.setBase(ResourceTypeEnum.GROUP); + memberSp.setType(SearchParamTypeEnum.REFERENCE); + memberSp.setXpath("Group.member.entity"); + memberSp.setXpathUsage(XPathUsageTypeEnum.NORMAL); + memberSp.setStatus(ConformanceResourceStatusEnum.RETIRED); + mySearchParameterDao.create(memberSp, mySrd); + + SearchParameter identifierSp = new SearchParameter(); + identifierSp.setCode("identifier"); + identifierSp.setBase(ResourceTypeEnum.GROUP); + identifierSp.setType(SearchParamTypeEnum.TOKEN); + identifierSp.setXpath("Group.identifier"); + identifierSp.setXpathUsage(XPathUsageTypeEnum.NORMAL); + identifierSp.setStatus(ConformanceResourceStatusEnum.RETIRED); + mySearchParameterDao.create(identifierSp, mySrd); + + mySearchParamRegsitry.forceRefresh(); + + Patient p = new Patient(); + p.addName().addGiven("G"); + IIdType pid = myPatientDao.create(p).getId().toUnqualifiedVersionless(); + + Group g = new Group(); + g.addIdentifier().setSystem("urn:foo").setValue("bar"); + g.addMember().getEntity().setReference(pid); + myGroupDao.create(g); + + assertThat(myResourceLinkDao.findAll(), empty()); + assertThat(ListUtil.filter(myResourceIndexedSearchParamTokenDao.findAll(), new ListUtil.Filter() { + @Override + public boolean isOut(ResourceIndexedSearchParamToken object) { + return !object.getResourceType().equals("Group") || object.isMissing(); + } + }), empty()); + } + @Test public void testSearchForExtensionReferenceWithNonMatchingTarget() { SearchParameter siblingSp = new SearchParameter(); diff --git a/hapi-fhir-jpaserver-base/src/test/java/ca/uhn/fhir/jpa/dao/dstu3/FhirResourceDaoDstu3SearchCustomSearchParamTest.java b/hapi-fhir-jpaserver-base/src/test/java/ca/uhn/fhir/jpa/dao/dstu3/FhirResourceDaoDstu3SearchCustomSearchParamTest.java index 47b10e2dc81..b956c0abb9d 100644 --- a/hapi-fhir-jpaserver-base/src/test/java/ca/uhn/fhir/jpa/dao/dstu3/FhirResourceDaoDstu3SearchCustomSearchParamTest.java +++ b/hapi-fhir-jpaserver-base/src/test/java/ca/uhn/fhir/jpa/dao/dstu3/FhirResourceDaoDstu3SearchCustomSearchParamTest.java @@ -28,6 +28,23 @@ public class FhirResourceDaoDstu3SearchCustomSearchParamTest extends BaseJpaDstu myDaoConfig.setReuseCachedSearchResultsForMillis(null); } + @Test + public void testCreateInvalidNoBase() { + SearchParameter fooSp = new SearchParameter(); + fooSp.setCode("foo"); + fooSp.setType(org.hl7.fhir.dstu3.model.Enumerations.SearchParamType.TOKEN); + fooSp.setTitle("FOO SP"); + fooSp.setExpression("Patient.gender"); + fooSp.setXpathUsage(org.hl7.fhir.dstu3.model.SearchParameter.XPathUsageType.NORMAL); + fooSp.setStatus(org.hl7.fhir.dstu3.model.Enumerations.PublicationStatus.ACTIVE); + try { + mySearchParameterDao.create(fooSp, mySrd); + fail(); + } catch (UnprocessableEntityException e) { + assertEquals("SearchParameter.base is missing", e.getMessage()); + } + } + @Test public void testCreateInvalidParamInvalidResourceName() { SearchParameter fooSp = new SearchParameter(); @@ -46,23 +63,6 @@ public class FhirResourceDaoDstu3SearchCustomSearchParamTest extends BaseJpaDstu } } - @Test - public void testCreateInvalidNoBase() { - SearchParameter fooSp = new SearchParameter(); - fooSp.setCode("foo"); - fooSp.setType(org.hl7.fhir.dstu3.model.Enumerations.SearchParamType.TOKEN); - fooSp.setTitle("FOO SP"); - fooSp.setExpression("Patient.gender"); - fooSp.setXpathUsage(org.hl7.fhir.dstu3.model.SearchParameter.XPathUsageType.NORMAL); - fooSp.setStatus(org.hl7.fhir.dstu3.model.Enumerations.PublicationStatus.ACTIVE); - try { - mySearchParameterDao.create(fooSp, mySrd); - fail(); - } catch (UnprocessableEntityException e) { - assertEquals("SearchParameter.base is missing", e.getMessage()); - } - } - @Test public void testCreateInvalidParamMismatchedResourceName() { SearchParameter fooSp = new SearchParameter(); @@ -136,6 +136,36 @@ public class FhirResourceDaoDstu3SearchCustomSearchParamTest extends BaseJpaDstu } + @Test + public void testCustomReferenceParameter() throws Exception { + SearchParameter sp = new SearchParameter(); + sp.addBase("Patient"); + sp.setCode("myDoctor"); + sp.setType(org.hl7.fhir.dstu3.model.Enumerations.SearchParamType.REFERENCE); + sp.setTitle("My Doctor"); + sp.setExpression("Patient.extension('http://fmcna.com/myDoctor')"); + sp.setXpathUsage(org.hl7.fhir.dstu3.model.SearchParameter.XPathUsageType.NORMAL); + sp.setStatus(org.hl7.fhir.dstu3.model.Enumerations.PublicationStatus.ACTIVE); + mySearchParameterDao.create(sp); + + mySearchParamRegsitry.forceRefresh(); + + org.hl7.fhir.dstu3.model.Practitioner pract = new org.hl7.fhir.dstu3.model.Practitioner(); + pract.setId("A"); + pract.addName().setFamily("PRACT"); + myPractitionerDao.update(pract); + + Patient pat = myFhirCtx.newJsonParser().parseResource(Patient.class, loadClasspath("/dstu3_custom_resource_patient.json")); + IIdType pid = myPatientDao.create(pat, mySrd).getId().toUnqualifiedVersionless(); + + SearchParameterMap params = new SearchParameterMap(); + params.add("myDoctor", new ReferenceParam("A")); + IBundleProvider outcome = myPatientDao.search(params); + List ids = toUnqualifiedVersionlessIdValues(outcome); + ourLog.info("IDS: " + ids); + assertThat(ids, contains(pid.getValue())); + } + @Test public void testExtensionWithNoValueIndexesWithoutFailure() { SearchParameter eyeColourSp = new SearchParameter(); @@ -158,34 +188,197 @@ public class FhirResourceDaoDstu3SearchCustomSearchParamTest extends BaseJpaDstu } @Test - public void testSearchOnMultivalue() throws FHIRException { - SearchParameter displaySp = new SearchParameter(); - displaySp.addBase("MedicationStatement"); - displaySp.setCode("display"); - displaySp.setType(Enumerations.SearchParamType.STRING); - displaySp.setTitle("Display"); - displaySp.setExpression("MedicationStatement.medication.as(CodeableConcept).coding.display"); - displaySp.setXpathUsage(org.hl7.fhir.dstu3.model.SearchParameter.XPathUsageType.NORMAL); - displaySp.setStatus(org.hl7.fhir.dstu3.model.Enumerations.PublicationStatus.ACTIVE); - mySearchParameterDao.create(displaySp, mySrd); + public void testIncludeExtensionReferenceAsRecurse() { + SearchParameter attendingSp = new SearchParameter(); + attendingSp.addBase("Patient"); + attendingSp.setCode("attending"); + attendingSp.setType(org.hl7.fhir.dstu3.model.Enumerations.SearchParamType.REFERENCE); + attendingSp.setTitle("Attending"); + attendingSp.setExpression("Patient.extension('http://acme.org/attending')"); + attendingSp.setXpathUsage(org.hl7.fhir.dstu3.model.SearchParameter.XPathUsageType.NORMAL); + attendingSp.setStatus(org.hl7.fhir.dstu3.model.Enumerations.PublicationStatus.ACTIVE); + attendingSp.getTarget().add(new CodeType("Practitioner")); + IIdType spId = mySearchParameterDao.create(attendingSp, mySrd).getId().toUnqualifiedVersionless(); mySearchParamRegsitry.forceRefresh(); - MedicationStatement ms1 = new MedicationStatement(); - ms1.setMedication(new CodeableConcept()); - ms1.getMedicationCodeableConcept().addCoding().setDisplay("AAA"); - String id1 = myMedicationStatementDao.create(ms1).getId().toUnqualifiedVersionless().getValue(); + Practitioner p1 = new Practitioner(); + p1.addName().setFamily("P1"); + IIdType p1id = myPractitionerDao.create(p1).getId().toUnqualifiedVersionless(); - MedicationStatement ms2 = new MedicationStatement(); - ms2.setMedication(new CodeableConcept()); - ms2.getMedicationCodeableConcept().addCoding().setDisplay("BBB"); - myMedicationStatementDao.create(ms2).getId().toUnqualifiedVersionless().getValue(); + Patient p2 = new Patient(); + p2.addName().setFamily("P2"); + p2.addExtension().setUrl("http://acme.org/attending").setValue(new Reference(p1id)); + IIdType p2id = myPatientDao.create(p2).getId().toUnqualifiedVersionless(); + + Appointment app = new Appointment(); + app.addParticipant().getActor().setReference(p2id.getValue()); + IIdType appId = myAppointmentDao.create(app).getId().toUnqualifiedVersionless(); + + SearchParameterMap map; + IBundleProvider results; + List foundResources; + + map = new SearchParameterMap(); + map.addInclude(new Include("Appointment:patient", true)); + map.addInclude(new Include("Patient:attending", true)); + results = myAppointmentDao.search(map); + foundResources = toUnqualifiedVersionlessIdValues(results); + assertThat(foundResources, contains(appId.getValue(), p2id.getValue(), p1id.getValue())); + + } + + @Test + public void testSearchForExtensionReferenceWithNonMatchingTarget() { + SearchParameter siblingSp = new SearchParameter(); + siblingSp.addBase("Patient"); + siblingSp.setCode("sibling"); + siblingSp.setType(org.hl7.fhir.dstu3.model.Enumerations.SearchParamType.REFERENCE); + siblingSp.setTitle("Sibling"); + siblingSp.setExpression("Patient.extension('http://acme.org/sibling')"); + siblingSp.setXpathUsage(org.hl7.fhir.dstu3.model.SearchParameter.XPathUsageType.NORMAL); + siblingSp.setStatus(org.hl7.fhir.dstu3.model.Enumerations.PublicationStatus.ACTIVE); + siblingSp.getTarget().add(new CodeType("Organization")); + mySearchParameterDao.create(siblingSp, mySrd); + + mySearchParamRegsitry.forceRefresh(); + + Patient p1 = new Patient(); + p1.addName().setFamily("P1"); + IIdType p1id = myPatientDao.create(p1).getId().toUnqualifiedVersionless(); + + Patient p2 = new Patient(); + p2.addName().setFamily("P2"); + p2.addExtension().setUrl("http://acme.org/sibling").setValue(new Reference(p1id)); + IIdType p2id = myPatientDao.create(p2).getId().toUnqualifiedVersionless(); + + SearchParameterMap map; + IBundleProvider results; + List foundResources; + + // Search by ref + map = new SearchParameterMap(); + map.add("sibling", new ReferenceParam(p1id.getValue())); + results = myPatientDao.search(map); + foundResources = toUnqualifiedVersionlessIdValues(results); + assertThat(foundResources, empty()); + + // Search by chain + map = new SearchParameterMap(); + map.add("sibling", new ReferenceParam("name", "P1")); + results = myPatientDao.search(map); + foundResources = toUnqualifiedVersionlessIdValues(results); + assertThat(foundResources, empty()); + + } + + @Test + public void testSearchForExtensionReferenceWithTarget() { + SearchParameter siblingSp = new SearchParameter(); + siblingSp.addBase("Patient"); + siblingSp.setCode("sibling"); + siblingSp.setType(org.hl7.fhir.dstu3.model.Enumerations.SearchParamType.REFERENCE); + siblingSp.setTitle("Sibling"); + siblingSp.setExpression("Patient.extension('http://acme.org/sibling')"); + siblingSp.setXpathUsage(org.hl7.fhir.dstu3.model.SearchParameter.XPathUsageType.NORMAL); + siblingSp.setStatus(org.hl7.fhir.dstu3.model.Enumerations.PublicationStatus.ACTIVE); + siblingSp.getTarget().add(new CodeType("Patient")); + mySearchParameterDao.create(siblingSp, mySrd); + + mySearchParamRegsitry.forceRefresh(); + + Patient p1 = new Patient(); + p1.addName().setFamily("P1"); + IIdType p1id = myPatientDao.create(p1).getId().toUnqualifiedVersionless(); + + Patient p2 = new Patient(); + p2.addName().setFamily("P2"); + p2.addExtension().setUrl("http://acme.org/sibling").setValue(new Reference(p1id)); + IIdType p2id = myPatientDao.create(p2).getId().toUnqualifiedVersionless(); + + Appointment app = new Appointment(); + app.addParticipant().getActor().setReference(p2id.getValue()); + IIdType appid = myAppointmentDao.create(app).getId().toUnqualifiedVersionless(); + + SearchParameterMap map; + IBundleProvider results; + List foundResources; + + // Search by ref + map = new SearchParameterMap(); + map.add("sibling", new ReferenceParam(p1id.getValue())); + results = myPatientDao.search(map); + foundResources = toUnqualifiedVersionlessIdValues(results); + assertThat(foundResources, contains(p2id.getValue())); + + // Search by chain + map = new SearchParameterMap(); + map.add("sibling", new ReferenceParam("name", "P1")); + results = myPatientDao.search(map); + foundResources = toUnqualifiedVersionlessIdValues(results); + assertThat(foundResources, contains(p2id.getValue())); + + // Search by two level chain + map = new SearchParameterMap(); + map.add("patient", new ReferenceParam("sibling.name", "P1")); + results = myAppointmentDao.search(map); + foundResources = toUnqualifiedVersionlessIdValues(results); + assertThat(foundResources, containsInAnyOrder(appid.getValue())); + + } + + @Test + public void testSearchForExtensionReferenceWithoutTarget() { + SearchParameter siblingSp = new SearchParameter(); + siblingSp.addBase("Patient"); + siblingSp.setCode("sibling"); + siblingSp.setType(org.hl7.fhir.dstu3.model.Enumerations.SearchParamType.REFERENCE); + siblingSp.setTitle("Sibling"); + siblingSp.setExpression("Patient.extension('http://acme.org/sibling')"); + siblingSp.setXpathUsage(org.hl7.fhir.dstu3.model.SearchParameter.XPathUsageType.NORMAL); + siblingSp.setStatus(org.hl7.fhir.dstu3.model.Enumerations.PublicationStatus.ACTIVE); + mySearchParameterDao.create(siblingSp, mySrd); + + mySearchParamRegsitry.forceRefresh(); + + Patient p1 = new Patient(); + p1.addName().setFamily("P1"); + IIdType p1id = myPatientDao.create(p1).getId().toUnqualifiedVersionless(); + + Patient p2 = new Patient(); + p2.addName().setFamily("P2"); + p2.addExtension().setUrl("http://acme.org/sibling").setValue(new Reference(p1id)); + + IIdType p2id = myPatientDao.create(p2).getId().toUnqualifiedVersionless(); + Appointment app = new Appointment(); + app.addParticipant().getActor().setReference(p2id.getValue()); + IIdType appid = myAppointmentDao.create(app).getId().toUnqualifiedVersionless(); + + SearchParameterMap map; + IBundleProvider results; + List foundResources; + + // Search by ref + map = new SearchParameterMap(); + map.add("sibling", new ReferenceParam(p1id.getValue())); + results = myPatientDao.search(map); + foundResources = toUnqualifiedVersionlessIdValues(results); + assertThat(foundResources, contains(p2id.getValue())); + + // Search by chain + map = new SearchParameterMap(); + map.add("sibling", new ReferenceParam("name", "P1")); + results = myPatientDao.search(map); + foundResources = toUnqualifiedVersionlessIdValues(results); + assertThat(foundResources, contains(p2id.getValue())); + + // Search by two level chain + map = new SearchParameterMap(); + map.add("patient", new ReferenceParam("sibling.name", "P1")); + results = myAppointmentDao.search(map); + foundResources = toUnqualifiedVersionlessIdValues(results); + assertThat(foundResources, containsInAnyOrder(appid.getValue())); - SearchParameterMap map = new SearchParameterMap(); - map.setLoadSynchronous(true); - map.add("display", new StringParam("AAA")); - IBundleProvider results = myMedicationStatementDao.search(map); - assertThat(toUnqualifiedVersionlessIdValues(results), contains(id1)); } @@ -221,44 +414,6 @@ public class FhirResourceDaoDstu3SearchCustomSearchParamTest extends BaseJpaDstu assertThat(foundResources, contains(p1id.getValue())); } - - @Test - public void testSearchForExtensionTwoDeepCoding() { - SearchParameter siblingSp = new SearchParameter(); - siblingSp.addBase("Patient"); - siblingSp.setCode("foobar"); - siblingSp.setType(org.hl7.fhir.dstu3.model.Enumerations.SearchParamType.TOKEN); - siblingSp.setTitle("FooBar"); - siblingSp.setExpression("Patient.extension('http://acme.org/foo').extension('http://acme.org/bar')"); - siblingSp.setXpathUsage(org.hl7.fhir.dstu3.model.SearchParameter.XPathUsageType.NORMAL); - siblingSp.setStatus(org.hl7.fhir.dstu3.model.Enumerations.PublicationStatus.ACTIVE); - siblingSp.getTarget().add(new CodeType("Organization")); - mySearchParameterDao.create(siblingSp, mySrd); - - mySearchParamRegsitry.forceRefresh(); - - Patient patient = new Patient(); - patient.addName().setFamily("P2"); - Extension extParent = patient - .addExtension() - .setUrl("http://acme.org/foo"); - extParent - .addExtension() - .setUrl("http://acme.org/bar") - .setValue(new Coding().setSystem("foo").setCode("bar")); - - IIdType p2id = myPatientDao.create(patient).getId().toUnqualifiedVersionless(); - - SearchParameterMap map; - IBundleProvider results; - List foundResources; - - map = new SearchParameterMap(); - map.add("foobar", new TokenParam("foo", "bar")); - results = myPatientDao.search(map); - foundResources = toUnqualifiedVersionlessIdValues(results); - assertThat(foundResources, contains(p2id.getValue())); - } @Test public void testSearchForExtensionTwoDeepCodeableConcept() { @@ -284,13 +439,13 @@ public class FhirResourceDaoDstu3SearchCustomSearchParamTest extends BaseJpaDstu .addExtension() .setUrl("http://acme.org/bar") .setValue(new CodeableConcept().addCoding(new Coding().setSystem("foo").setCode("bar"))); - + IIdType p2id = myPatientDao.create(patient).getId().toUnqualifiedVersionless(); SearchParameterMap map; IBundleProvider results; List foundResources; - + map = new SearchParameterMap(); map.add("foobar", new TokenParam("foo", "bar")); results = myPatientDao.search(map); @@ -299,128 +454,38 @@ public class FhirResourceDaoDstu3SearchCustomSearchParamTest extends BaseJpaDstu } @Test - public void testSearchForExtensionTwoDeepReferenceWrongType() { + public void testSearchForExtensionTwoDeepCoding() { SearchParameter siblingSp = new SearchParameter(); siblingSp.addBase("Patient"); siblingSp.setCode("foobar"); - siblingSp.setType(org.hl7.fhir.dstu3.model.Enumerations.SearchParamType.REFERENCE); + siblingSp.setType(org.hl7.fhir.dstu3.model.Enumerations.SearchParamType.TOKEN); siblingSp.setTitle("FooBar"); siblingSp.setExpression("Patient.extension('http://acme.org/foo').extension('http://acme.org/bar')"); siblingSp.setXpathUsage(org.hl7.fhir.dstu3.model.SearchParameter.XPathUsageType.NORMAL); siblingSp.setStatus(org.hl7.fhir.dstu3.model.Enumerations.PublicationStatus.ACTIVE); - siblingSp.getTarget().add(new CodeType("Observation")); + siblingSp.getTarget().add(new CodeType("Organization")); mySearchParameterDao.create(siblingSp, mySrd); mySearchParamRegsitry.forceRefresh(); - Appointment apt = new Appointment(); - apt.setStatus(AppointmentStatus.ARRIVED); - IIdType aptId = myAppointmentDao.create(apt).getId().toUnqualifiedVersionless(); - Patient patient = new Patient(); patient.addName().setFamily("P2"); Extension extParent = patient .addExtension() .setUrl("http://acme.org/foo"); - extParent .addExtension() .setUrl("http://acme.org/bar") - .setValue(new Reference(aptId.getValue())); - + .setValue(new Coding().setSystem("foo").setCode("bar")); + IIdType p2id = myPatientDao.create(patient).getId().toUnqualifiedVersionless(); SearchParameterMap map; IBundleProvider results; List foundResources; - + map = new SearchParameterMap(); - map.add("foobar", new ReferenceParam(aptId.getValue())); - results = myPatientDao.search(map); - foundResources = toUnqualifiedVersionlessIdValues(results); - assertThat(foundResources, empty()); - } - - @Test - public void testSearchForExtensionTwoDeepReferenceWithoutType() { - SearchParameter siblingSp = new SearchParameter(); - siblingSp.addBase("Patient"); - siblingSp.setCode("foobar"); - siblingSp.setType(org.hl7.fhir.dstu3.model.Enumerations.SearchParamType.REFERENCE); - siblingSp.setTitle("FooBar"); - siblingSp.setExpression("Patient.extension('http://acme.org/foo').extension('http://acme.org/bar')"); - siblingSp.setXpathUsage(org.hl7.fhir.dstu3.model.SearchParameter.XPathUsageType.NORMAL); - siblingSp.setStatus(org.hl7.fhir.dstu3.model.Enumerations.PublicationStatus.ACTIVE); - mySearchParameterDao.create(siblingSp, mySrd); - - mySearchParamRegsitry.forceRefresh(); - - Appointment apt = new Appointment(); - apt.setStatus(AppointmentStatus.ARRIVED); - IIdType aptId = myAppointmentDao.create(apt).getId().toUnqualifiedVersionless(); - - Patient patient = new Patient(); - patient.addName().setFamily("P2"); - Extension extParent = patient - .addExtension() - .setUrl("http://acme.org/foo"); - - extParent - .addExtension() - .setUrl("http://acme.org/bar") - .setValue(new Reference(aptId.getValue())); - - IIdType p2id = myPatientDao.create(patient).getId().toUnqualifiedVersionless(); - - SearchParameterMap map; - IBundleProvider results; - List foundResources; - - map = new SearchParameterMap(); - map.add("foobar", new ReferenceParam(aptId.getValue())); - results = myPatientDao.search(map); - foundResources = toUnqualifiedVersionlessIdValues(results); - assertThat(foundResources, contains(p2id.getValue())); - } - - @Test - public void testSearchForExtensionTwoDeepReference() { - SearchParameter siblingSp = new SearchParameter(); - siblingSp.addBase("Patient"); - siblingSp.setCode("foobar"); - siblingSp.setType(org.hl7.fhir.dstu3.model.Enumerations.SearchParamType.REFERENCE); - siblingSp.setTitle("FooBar"); - siblingSp.setExpression("Patient.extension('http://acme.org/foo').extension('http://acme.org/bar')"); - siblingSp.setXpathUsage(org.hl7.fhir.dstu3.model.SearchParameter.XPathUsageType.NORMAL); - siblingSp.setStatus(org.hl7.fhir.dstu3.model.Enumerations.PublicationStatus.ACTIVE); - siblingSp.getTarget().add(new CodeType("Appointment")); - mySearchParameterDao.create(siblingSp, mySrd); - - mySearchParamRegsitry.forceRefresh(); - - Appointment apt = new Appointment(); - apt.setStatus(AppointmentStatus.ARRIVED); - IIdType aptId = myAppointmentDao.create(apt).getId().toUnqualifiedVersionless(); - - Patient patient = new Patient(); - patient.addName().setFamily("P2"); - Extension extParent = patient - .addExtension() - .setUrl("http://acme.org/foo"); - - extParent - .addExtension() - .setUrl("http://acme.org/bar") - .setValue(new Reference(aptId.getValue())); - - IIdType p2id = myPatientDao.create(patient).getId().toUnqualifiedVersionless(); - - SearchParameterMap map; - IBundleProvider results; - List foundResources; - - map = new SearchParameterMap(); - map.add("foobar", new ReferenceParam(aptId.getValue())); + map.add("foobar", new TokenParam("foo", "bar")); results = myPatientDao.search(map); foundResources = toUnqualifiedVersionlessIdValues(results); assertThat(foundResources, contains(p2id.getValue())); @@ -443,24 +508,24 @@ public class FhirResourceDaoDstu3SearchCustomSearchParamTest extends BaseJpaDstu Appointment apt = new Appointment(); apt.setStatus(AppointmentStatus.ARRIVED); IIdType aptId = myAppointmentDao.create(apt).getId().toUnqualifiedVersionless(); - + Patient patient = new Patient(); patient.addName().setFamily("P2"); Extension extParent = patient .addExtension() .setUrl("http://acme.org/foo"); - + extParent .addExtension() .setUrl("http://acme.org/bar") .setValue(new DateType("2012-01-02")); - + IIdType p2id = myPatientDao.create(patient).getId().toUnqualifiedVersionless(); SearchParameterMap map; IBundleProvider results; List foundResources; - + map = new SearchParameterMap(); map.add("foobar", new DateParam("2012-01-02")); results = myPatientDao.search(map); @@ -468,43 +533,6 @@ public class FhirResourceDaoDstu3SearchCustomSearchParamTest extends BaseJpaDstu assertThat(foundResources, contains(p2id.getValue())); } - @Test - public void testSearchForExtensionTwoDeepNumber() { - SearchParameter siblingSp = new SearchParameter(); - siblingSp.addBase("Patient"); - siblingSp.setCode("foobar"); - siblingSp.setType(org.hl7.fhir.dstu3.model.Enumerations.SearchParamType.NUMBER); - siblingSp.setTitle("FooBar"); - siblingSp.setExpression("Patient.extension('http://acme.org/foo').extension('http://acme.org/bar')"); - siblingSp.setXpathUsage(org.hl7.fhir.dstu3.model.SearchParameter.XPathUsageType.NORMAL); - siblingSp.setStatus(org.hl7.fhir.dstu3.model.Enumerations.PublicationStatus.ACTIVE); - mySearchParameterDao.create(siblingSp, mySrd); - - mySearchParamRegsitry.forceRefresh(); - - Patient patient = new Patient(); - patient.addName().setFamily("P2"); - Extension extParent = patient - .addExtension() - .setUrl("http://acme.org/foo"); - extParent - .addExtension() - .setUrl("http://acme.org/bar") - .setValue(new IntegerType(5)); - - IIdType p2id = myPatientDao.create(patient).getId().toUnqualifiedVersionless(); - - SearchParameterMap map; - IBundleProvider results; - List foundResources; - - map = new SearchParameterMap(); - map.add("foobar", new NumberParam("5")); - results = myPatientDao.search(map); - foundResources = toUnqualifiedVersionlessIdValues(results); - assertThat(foundResources, contains(p2id.getValue())); - } - @Test public void testSearchForExtensionTwoDeepDecimal() { SearchParameter siblingSp = new SearchParameter(); @@ -542,6 +570,171 @@ public class FhirResourceDaoDstu3SearchCustomSearchParamTest extends BaseJpaDstu assertThat(foundResources, contains(p2id.getValue())); } + @Test + public void testSearchForExtensionTwoDeepNumber() { + SearchParameter siblingSp = new SearchParameter(); + siblingSp.addBase("Patient"); + siblingSp.setCode("foobar"); + siblingSp.setType(org.hl7.fhir.dstu3.model.Enumerations.SearchParamType.NUMBER); + siblingSp.setTitle("FooBar"); + siblingSp.setExpression("Patient.extension('http://acme.org/foo').extension('http://acme.org/bar')"); + siblingSp.setXpathUsage(org.hl7.fhir.dstu3.model.SearchParameter.XPathUsageType.NORMAL); + siblingSp.setStatus(org.hl7.fhir.dstu3.model.Enumerations.PublicationStatus.ACTIVE); + mySearchParameterDao.create(siblingSp, mySrd); + + mySearchParamRegsitry.forceRefresh(); + + Patient patient = new Patient(); + patient.addName().setFamily("P2"); + Extension extParent = patient + .addExtension() + .setUrl("http://acme.org/foo"); + extParent + .addExtension() + .setUrl("http://acme.org/bar") + .setValue(new IntegerType(5)); + + IIdType p2id = myPatientDao.create(patient).getId().toUnqualifiedVersionless(); + + SearchParameterMap map; + IBundleProvider results; + List foundResources; + + map = new SearchParameterMap(); + map.add("foobar", new NumberParam("5")); + results = myPatientDao.search(map); + foundResources = toUnqualifiedVersionlessIdValues(results); + assertThat(foundResources, contains(p2id.getValue())); + } + + @Test + public void testSearchForExtensionTwoDeepReference() { + SearchParameter siblingSp = new SearchParameter(); + siblingSp.addBase("Patient"); + siblingSp.setCode("foobar"); + siblingSp.setType(org.hl7.fhir.dstu3.model.Enumerations.SearchParamType.REFERENCE); + siblingSp.setTitle("FooBar"); + siblingSp.setExpression("Patient.extension('http://acme.org/foo').extension('http://acme.org/bar')"); + siblingSp.setXpathUsage(org.hl7.fhir.dstu3.model.SearchParameter.XPathUsageType.NORMAL); + siblingSp.setStatus(org.hl7.fhir.dstu3.model.Enumerations.PublicationStatus.ACTIVE); + siblingSp.getTarget().add(new CodeType("Appointment")); + mySearchParameterDao.create(siblingSp, mySrd); + + mySearchParamRegsitry.forceRefresh(); + + Appointment apt = new Appointment(); + apt.setStatus(AppointmentStatus.ARRIVED); + IIdType aptId = myAppointmentDao.create(apt).getId().toUnqualifiedVersionless(); + + Patient patient = new Patient(); + patient.addName().setFamily("P2"); + Extension extParent = patient + .addExtension() + .setUrl("http://acme.org/foo"); + + extParent + .addExtension() + .setUrl("http://acme.org/bar") + .setValue(new Reference(aptId.getValue())); + + IIdType p2id = myPatientDao.create(patient).getId().toUnqualifiedVersionless(); + + SearchParameterMap map; + IBundleProvider results; + List foundResources; + + map = new SearchParameterMap(); + map.add("foobar", new ReferenceParam(aptId.getValue())); + results = myPatientDao.search(map); + foundResources = toUnqualifiedVersionlessIdValues(results); + assertThat(foundResources, contains(p2id.getValue())); + } + + @Test + public void testSearchForExtensionTwoDeepReferenceWithoutType() { + SearchParameter siblingSp = new SearchParameter(); + siblingSp.addBase("Patient"); + siblingSp.setCode("foobar"); + siblingSp.setType(org.hl7.fhir.dstu3.model.Enumerations.SearchParamType.REFERENCE); + siblingSp.setTitle("FooBar"); + siblingSp.setExpression("Patient.extension('http://acme.org/foo').extension('http://acme.org/bar')"); + siblingSp.setXpathUsage(org.hl7.fhir.dstu3.model.SearchParameter.XPathUsageType.NORMAL); + siblingSp.setStatus(org.hl7.fhir.dstu3.model.Enumerations.PublicationStatus.ACTIVE); + mySearchParameterDao.create(siblingSp, mySrd); + + mySearchParamRegsitry.forceRefresh(); + + Appointment apt = new Appointment(); + apt.setStatus(AppointmentStatus.ARRIVED); + IIdType aptId = myAppointmentDao.create(apt).getId().toUnqualifiedVersionless(); + + Patient patient = new Patient(); + patient.addName().setFamily("P2"); + Extension extParent = patient + .addExtension() + .setUrl("http://acme.org/foo"); + + extParent + .addExtension() + .setUrl("http://acme.org/bar") + .setValue(new Reference(aptId.getValue())); + + IIdType p2id = myPatientDao.create(patient).getId().toUnqualifiedVersionless(); + + SearchParameterMap map; + IBundleProvider results; + List foundResources; + + map = new SearchParameterMap(); + map.add("foobar", new ReferenceParam(aptId.getValue())); + results = myPatientDao.search(map); + foundResources = toUnqualifiedVersionlessIdValues(results); + assertThat(foundResources, contains(p2id.getValue())); + } + + @Test + public void testSearchForExtensionTwoDeepReferenceWrongType() { + SearchParameter siblingSp = new SearchParameter(); + siblingSp.addBase("Patient"); + siblingSp.setCode("foobar"); + siblingSp.setType(org.hl7.fhir.dstu3.model.Enumerations.SearchParamType.REFERENCE); + siblingSp.setTitle("FooBar"); + siblingSp.setExpression("Patient.extension('http://acme.org/foo').extension('http://acme.org/bar')"); + siblingSp.setXpathUsage(org.hl7.fhir.dstu3.model.SearchParameter.XPathUsageType.NORMAL); + siblingSp.setStatus(org.hl7.fhir.dstu3.model.Enumerations.PublicationStatus.ACTIVE); + siblingSp.getTarget().add(new CodeType("Observation")); + mySearchParameterDao.create(siblingSp, mySrd); + + mySearchParamRegsitry.forceRefresh(); + + Appointment apt = new Appointment(); + apt.setStatus(AppointmentStatus.ARRIVED); + IIdType aptId = myAppointmentDao.create(apt).getId().toUnqualifiedVersionless(); + + Patient patient = new Patient(); + patient.addName().setFamily("P2"); + Extension extParent = patient + .addExtension() + .setUrl("http://acme.org/foo"); + + extParent + .addExtension() + .setUrl("http://acme.org/bar") + .setValue(new Reference(aptId.getValue())); + + IIdType p2id = myPatientDao.create(patient).getId().toUnqualifiedVersionless(); + + SearchParameterMap map; + IBundleProvider results; + List foundResources; + + map = new SearchParameterMap(); + map.add("foobar", new ReferenceParam(aptId.getValue())); + results = myPatientDao.search(map); + foundResources = toUnqualifiedVersionlessIdValues(results); + assertThat(foundResources, empty()); + } + @Test public void testSearchForExtensionTwoDeepString() { SearchParameter siblingSp = new SearchParameter(); @@ -565,13 +758,13 @@ public class FhirResourceDaoDstu3SearchCustomSearchParamTest extends BaseJpaDstu .addExtension() .setUrl("http://acme.org/bar") .setValue(new StringType("HELLOHELLO")); - + IIdType p2id = myPatientDao.create(patient).getId().toUnqualifiedVersionless(); SearchParameterMap map; IBundleProvider results; List foundResources; - + map = new SearchParameterMap(); map.add("foobar", new StringParam("hello")); results = myPatientDao.search(map); @@ -580,199 +773,34 @@ public class FhirResourceDaoDstu3SearchCustomSearchParamTest extends BaseJpaDstu } @Test - public void testSearchForExtensionReferenceWithNonMatchingTarget() { - SearchParameter siblingSp = new SearchParameter(); - siblingSp.addBase("Patient"); - siblingSp.setCode("sibling"); - siblingSp.setType(org.hl7.fhir.dstu3.model.Enumerations.SearchParamType.REFERENCE); - siblingSp.setTitle("Sibling"); - siblingSp.setExpression("Patient.extension('http://acme.org/sibling')"); - siblingSp.setXpathUsage(org.hl7.fhir.dstu3.model.SearchParameter.XPathUsageType.NORMAL); - siblingSp.setStatus(org.hl7.fhir.dstu3.model.Enumerations.PublicationStatus.ACTIVE); - siblingSp.getTarget().add(new CodeType("Organization")); - mySearchParameterDao.create(siblingSp, mySrd); + public void testSearchOnMultivalue() throws FHIRException { + SearchParameter displaySp = new SearchParameter(); + displaySp.addBase("MedicationStatement"); + displaySp.setCode("display"); + displaySp.setType(Enumerations.SearchParamType.STRING); + displaySp.setTitle("Display"); + displaySp.setExpression("MedicationStatement.medication.as(CodeableConcept).coding.display"); + displaySp.setXpathUsage(org.hl7.fhir.dstu3.model.SearchParameter.XPathUsageType.NORMAL); + displaySp.setStatus(org.hl7.fhir.dstu3.model.Enumerations.PublicationStatus.ACTIVE); + mySearchParameterDao.create(displaySp, mySrd); mySearchParamRegsitry.forceRefresh(); - Patient p1 = new Patient(); - p1.addName().setFamily("P1"); - IIdType p1id = myPatientDao.create(p1).getId().toUnqualifiedVersionless(); + MedicationStatement ms1 = new MedicationStatement(); + ms1.setMedication(new CodeableConcept()); + ms1.getMedicationCodeableConcept().addCoding().setDisplay("AAA"); + String id1 = myMedicationStatementDao.create(ms1).getId().toUnqualifiedVersionless().getValue(); - Patient p2 = new Patient(); - p2.addName().setFamily("P2"); - p2.addExtension().setUrl("http://acme.org/sibling").setValue(new Reference(p1id)); - IIdType p2id = myPatientDao.create(p2).getId().toUnqualifiedVersionless(); + MedicationStatement ms2 = new MedicationStatement(); + ms2.setMedication(new CodeableConcept()); + ms2.getMedicationCodeableConcept().addCoding().setDisplay("BBB"); + myMedicationStatementDao.create(ms2).getId().toUnqualifiedVersionless().getValue(); - SearchParameterMap map; - IBundleProvider results; - List foundResources; - - // Search by ref - map = new SearchParameterMap(); - map.add("sibling", new ReferenceParam(p1id.getValue())); - results = myPatientDao.search(map); - foundResources = toUnqualifiedVersionlessIdValues(results); - assertThat(foundResources, empty()); - - // Search by chain - map = new SearchParameterMap(); - map.add("sibling", new ReferenceParam("name", "P1")); - results = myPatientDao.search(map); - foundResources = toUnqualifiedVersionlessIdValues(results); - assertThat(foundResources, empty()); - - } - - - - @Test - public void testSearchForExtensionReferenceWithoutTarget() { - SearchParameter siblingSp = new SearchParameter(); - siblingSp.addBase("Patient"); - siblingSp.setCode("sibling"); - siblingSp.setType(org.hl7.fhir.dstu3.model.Enumerations.SearchParamType.REFERENCE); - siblingSp.setTitle("Sibling"); - siblingSp.setExpression("Patient.extension('http://acme.org/sibling')"); - siblingSp.setXpathUsage(org.hl7.fhir.dstu3.model.SearchParameter.XPathUsageType.NORMAL); - siblingSp.setStatus(org.hl7.fhir.dstu3.model.Enumerations.PublicationStatus.ACTIVE); - mySearchParameterDao.create(siblingSp, mySrd); - - mySearchParamRegsitry.forceRefresh(); - - Patient p1 = new Patient(); - p1.addName().setFamily("P1"); - IIdType p1id = myPatientDao.create(p1).getId().toUnqualifiedVersionless(); - - Patient p2 = new Patient(); - p2.addName().setFamily("P2"); - p2.addExtension().setUrl("http://acme.org/sibling").setValue(new Reference(p1id)); - - IIdType p2id = myPatientDao.create(p2).getId().toUnqualifiedVersionless(); - Appointment app = new Appointment(); - app.addParticipant().getActor().setReference(p2id.getValue()); - IIdType appid = myAppointmentDao.create(app).getId().toUnqualifiedVersionless(); - - SearchParameterMap map; - IBundleProvider results; - List foundResources; - - // Search by ref - map = new SearchParameterMap(); - map.add("sibling", new ReferenceParam(p1id.getValue())); - results = myPatientDao.search(map); - foundResources = toUnqualifiedVersionlessIdValues(results); - assertThat(foundResources, contains(p2id.getValue())); - - // Search by chain - map = new SearchParameterMap(); - map.add("sibling", new ReferenceParam("name", "P1")); - results = myPatientDao.search(map); - foundResources = toUnqualifiedVersionlessIdValues(results); - assertThat(foundResources, contains(p2id.getValue())); - - // Search by two level chain - map = new SearchParameterMap(); - map.add("patient", new ReferenceParam("sibling.name", "P1")); - results = myAppointmentDao.search(map); - foundResources = toUnqualifiedVersionlessIdValues(results); - assertThat(foundResources, containsInAnyOrder(appid.getValue())); - - - } - - @Test - public void testSearchForExtensionReferenceWithTarget() { - SearchParameter siblingSp = new SearchParameter(); - siblingSp.addBase("Patient"); - siblingSp.setCode("sibling"); - siblingSp.setType(org.hl7.fhir.dstu3.model.Enumerations.SearchParamType.REFERENCE); - siblingSp.setTitle("Sibling"); - siblingSp.setExpression("Patient.extension('http://acme.org/sibling')"); - siblingSp.setXpathUsage(org.hl7.fhir.dstu3.model.SearchParameter.XPathUsageType.NORMAL); - siblingSp.setStatus(org.hl7.fhir.dstu3.model.Enumerations.PublicationStatus.ACTIVE); - siblingSp.getTarget().add(new CodeType("Patient")); - mySearchParameterDao.create(siblingSp, mySrd); - - mySearchParamRegsitry.forceRefresh(); - - Patient p1 = new Patient(); - p1.addName().setFamily("P1"); - IIdType p1id = myPatientDao.create(p1).getId().toUnqualifiedVersionless(); - - Patient p2 = new Patient(); - p2.addName().setFamily("P2"); - p2.addExtension().setUrl("http://acme.org/sibling").setValue(new Reference(p1id)); - IIdType p2id = myPatientDao.create(p2).getId().toUnqualifiedVersionless(); - - Appointment app = new Appointment(); - app.addParticipant().getActor().setReference(p2id.getValue()); - IIdType appid = myAppointmentDao.create(app).getId().toUnqualifiedVersionless(); - - SearchParameterMap map; - IBundleProvider results; - List foundResources; - - // Search by ref - map = new SearchParameterMap(); - map.add("sibling", new ReferenceParam(p1id.getValue())); - results = myPatientDao.search(map); - foundResources = toUnqualifiedVersionlessIdValues(results); - assertThat(foundResources, contains(p2id.getValue())); - - // Search by chain - map = new SearchParameterMap(); - map.add("sibling", new ReferenceParam("name", "P1")); - results = myPatientDao.search(map); - foundResources = toUnqualifiedVersionlessIdValues(results); - assertThat(foundResources, contains(p2id.getValue())); - - // Search by two level chain - map = new SearchParameterMap(); - map.add("patient", new ReferenceParam("sibling.name", "P1")); - results = myAppointmentDao.search(map); - foundResources = toUnqualifiedVersionlessIdValues(results); - assertThat(foundResources, containsInAnyOrder(appid.getValue())); - - } - - @Test - public void testIncludeExtensionReferenceAsRecurse() { - SearchParameter attendingSp = new SearchParameter(); - attendingSp.addBase("Patient"); - attendingSp.setCode("attending"); - attendingSp.setType(org.hl7.fhir.dstu3.model.Enumerations.SearchParamType.REFERENCE); - attendingSp.setTitle("Attending"); - attendingSp.setExpression("Patient.extension('http://acme.org/attending')"); - attendingSp.setXpathUsage(org.hl7.fhir.dstu3.model.SearchParameter.XPathUsageType.NORMAL); - attendingSp.setStatus(org.hl7.fhir.dstu3.model.Enumerations.PublicationStatus.ACTIVE); - attendingSp.getTarget().add(new CodeType("Practitioner")); - IIdType spId = mySearchParameterDao.create(attendingSp, mySrd).getId().toUnqualifiedVersionless(); - - mySearchParamRegsitry.forceRefresh(); - - Practitioner p1 = new Practitioner(); - p1.addName().setFamily("P1"); - IIdType p1id = myPractitionerDao.create(p1).getId().toUnqualifiedVersionless(); - - Patient p2 = new Patient(); - p2.addName().setFamily("P2"); - p2.addExtension().setUrl("http://acme.org/attending").setValue(new Reference(p1id)); - IIdType p2id = myPatientDao.create(p2).getId().toUnqualifiedVersionless(); - - Appointment app = new Appointment(); - app.addParticipant().getActor().setReference(p2id.getValue()); - IIdType appId = myAppointmentDao.create(app).getId().toUnqualifiedVersionless(); - - SearchParameterMap map; - IBundleProvider results; - List foundResources; - - map = new SearchParameterMap(); - map.addInclude(new Include("Appointment:patient", true)); - map.addInclude(new Include("Patient:attending", true)); - results = myAppointmentDao.search(map); - foundResources = toUnqualifiedVersionlessIdValues(results); - assertThat(foundResources, contains(appId.getValue(), p2id.getValue(), p1id.getValue())); + SearchParameterMap map = new SearchParameterMap(); + map.setLoadSynchronous(true); + map.add("display", new StringParam("AAA")); + IBundleProvider results = myMedicationStatementDao.search(map); + assertThat(toUnqualifiedVersionlessIdValues(results), contains(id1)); } @@ -833,7 +861,7 @@ public class FhirResourceDaoDstu3SearchCustomSearchParamTest extends BaseJpaDstu assertEquals("Unknown search parameter foo for resource type Patient", e.getMessage()); } } - + @Test public void testSearchWithCustomParamDraft() { @@ -879,34 +907,6 @@ public class FhirResourceDaoDstu3SearchCustomSearchParamTest extends BaseJpaDstu assertThat(foundResources, contains(patId.getValue())); } - - @Test - public void testCustomReferenceParameter() throws Exception { - SearchParameter sp = new SearchParameter(); - sp.addBase("Patient"); - sp.setCode("myDoctor"); - sp.setType(org.hl7.fhir.dstu3.model.Enumerations.SearchParamType.REFERENCE); - sp.setTitle("My Doctor"); - sp.setExpression("Patient.extension('http://fmcna.com/myDoctor')"); - sp.setXpathUsage(org.hl7.fhir.dstu3.model.SearchParameter.XPathUsageType.NORMAL); - sp.setStatus(org.hl7.fhir.dstu3.model.Enumerations.PublicationStatus.ACTIVE); - mySearchParameterDao.create(sp); - - org.hl7.fhir.dstu3.model.Practitioner pract = new org.hl7.fhir.dstu3.model.Practitioner(); - pract.setId("A"); - pract.addName().setFamily("PRACT"); - myPractitionerDao.update(pract); - - Patient pat = myFhirCtx.newJsonParser().parseResource(Patient.class, loadClasspath("/dstu3_custom_resource_patient.json")); - IIdType pid = myPatientDao.create(pat, mySrd).getId().toUnqualifiedVersionless(); - - SearchParameterMap params = new SearchParameterMap(); - params.add("myDoctor", new ReferenceParam("A")); - IBundleProvider outcome = myPatientDao.search(params); - List ids = toUnqualifiedVersionlessIdValues(outcome); - ourLog.info("IDS: " + ids); - assertThat(ids, contains(pid.getValue())); - } @AfterClass public static void afterClassClearContext() { diff --git a/hapi-fhir-jpaserver-base/src/test/java/ca/uhn/fhir/jpa/dao/dstu3/SearchParamExtractorDstu3Test.java b/hapi-fhir-jpaserver-base/src/test/java/ca/uhn/fhir/jpa/dao/dstu3/SearchParamExtractorDstu3Test.java index b52520e579f..8ebb3497ea4 100644 --- a/hapi-fhir-jpaserver-base/src/test/java/ca/uhn/fhir/jpa/dao/dstu3/SearchParamExtractorDstu3Test.java +++ b/hapi-fhir-jpaserver-base/src/test/java/ca/uhn/fhir/jpa/dao/dstu3/SearchParamExtractorDstu3Test.java @@ -29,58 +29,58 @@ public class SearchParamExtractorDstu3Test { private static FhirContext ourCtx = FhirContext.forDstu3(); private static IValidationSupport ourValidationSupport; - @AfterClass - public static void afterClassClearContext() { - TestUtil.clearAllStaticFieldsForUnitTest(); - } - - @BeforeClass - public static void beforeClass() { - ourValidationSupport = new DefaultProfileValidationSupport(); - } - @Test public void testParamWithOrInPath() { Observation obs = new Observation(); obs.addCategory().addCoding().setSystem("SYSTEM").setCode("CODE"); - + ISearchParamRegistry searchParamRegistry = new ISearchParamRegistry() { - @Override - public Map getActiveSearchParams(String theResourceName) { - RuntimeResourceDefinition nextResDef = ourCtx.getResourceDefinition(theResourceName); - Map sps = new HashMap(); - for (RuntimeSearchParam nextSp : nextResDef.getSearchParams()) { - sps.put(nextSp.getName(), nextSp); - } - return sps; - } - - @Override - public List getActiveUniqueSearchParams(String theResourceName) { - throw new UnsupportedOperationException(); - } - - @Override - public List getActiveUniqueSearchParams(String theResourceName, Set theParamNames) { - throw new UnsupportedOperationException(); - } - @Override public void forceRefresh() { // nothing } + @Override + public RuntimeSearchParam getActiveSearchParam(String theResourceName, String theParamName) { + throw new UnsupportedOperationException(); + } + @Override public Map> getActiveSearchParams() { throw new UnsupportedOperationException(); } @Override - public RuntimeSearchParam getActiveSearchParam(String theResourceName, String theParamName) { + public Map getActiveSearchParams(String theResourceName) { + RuntimeResourceDefinition nextResDef = ourCtx.getResourceDefinition(theResourceName); + Map sps = new HashMap<>(); + for (RuntimeSearchParam nextSp : nextResDef.getSearchParams()) { + sps.put(nextSp.getName(), nextSp); + } + return sps; + } + + @Override + public List getActiveUniqueSearchParams(String theResourceName, Set theParamNames) { throw new UnsupportedOperationException(); } + + @Override + public List getActiveUniqueSearchParams(String theResourceName) { + throw new UnsupportedOperationException(); + } + + @Override + public void refreshCacheIfNecessary() { + // nothing + } + + @Override + public void requestRefresh() { + // nothing + } }; - + SearchParamExtractorDstu3 extractor = new SearchParamExtractorDstu3(ourCtx, ourValidationSupport, searchParamRegistry); Set tokens = extractor.extractSearchParamTokens(new ResourceTable(), obs); assertEquals(1, tokens.size()); @@ -89,5 +89,15 @@ public class SearchParamExtractorDstu3Test { assertEquals("SYSTEM", token.getSystem()); assertEquals("CODE", token.getValue()); } + + @AfterClass + public static void afterClassClearContext() { + TestUtil.clearAllStaticFieldsForUnitTest(); + } + + @BeforeClass + public static void beforeClass() { + ourValidationSupport = new DefaultProfileValidationSupport(); + } } diff --git a/hapi-fhir-jpaserver-base/src/test/java/ca/uhn/fhir/jpa/dao/r4/FhirResourceDaoR4SearchCustomSearchParamTest.java b/hapi-fhir-jpaserver-base/src/test/java/ca/uhn/fhir/jpa/dao/r4/FhirResourceDaoR4SearchCustomSearchParamTest.java index b35761ddacb..561076f8493 100644 --- a/hapi-fhir-jpaserver-base/src/test/java/ca/uhn/fhir/jpa/dao/r4/FhirResourceDaoR4SearchCustomSearchParamTest.java +++ b/hapi-fhir-jpaserver-base/src/test/java/ca/uhn/fhir/jpa/dao/r4/FhirResourceDaoR4SearchCustomSearchParamTest.java @@ -156,6 +156,8 @@ public class FhirResourceDaoR4SearchCustomSearchParamTest extends BaseJpaR4Test sp.setStatus(org.hl7.fhir.r4.model.Enumerations.PublicationStatus.ACTIVE); mySearchParameterDao.create(sp); + mySearchParamRegsitry.forceRefresh(); + org.hl7.fhir.r4.model.Practitioner pract = new org.hl7.fhir.r4.model.Practitioner(); pract.setId("A"); pract.addName().setFamily("PRACT"); diff --git a/hapi-fhir-jpaserver-base/src/test/java/ca/uhn/fhir/jpa/dao/r4/SearchParamExtractorR4Test.java b/hapi-fhir-jpaserver-base/src/test/java/ca/uhn/fhir/jpa/dao/r4/SearchParamExtractorR4Test.java index add3f47f8e5..fdd027d28fc 100644 --- a/hapi-fhir-jpaserver-base/src/test/java/ca/uhn/fhir/jpa/dao/r4/SearchParamExtractorR4Test.java +++ b/hapi-fhir-jpaserver-base/src/test/java/ca/uhn/fhir/jpa/dao/r4/SearchParamExtractorR4Test.java @@ -1,25 +1,94 @@ package ca.uhn.fhir.jpa.dao.r4; -import static org.junit.Assert.assertEquals; - -import java.util.*; - +import ca.uhn.fhir.context.FhirContext; +import ca.uhn.fhir.context.RuntimeResourceDefinition; +import ca.uhn.fhir.context.RuntimeSearchParam; +import ca.uhn.fhir.jpa.dao.ISearchParamRegistry; +import ca.uhn.fhir.jpa.entity.BaseResourceIndexedSearchParam; +import ca.uhn.fhir.jpa.entity.ResourceIndexedSearchParamToken; +import ca.uhn.fhir.jpa.entity.ResourceTable; import ca.uhn.fhir.jpa.search.JpaRuntimeSearchParam; +import ca.uhn.fhir.util.TestUtil; import org.hl7.fhir.r4.hapi.ctx.DefaultProfileValidationSupport; import org.hl7.fhir.r4.hapi.ctx.IValidationSupport; import org.hl7.fhir.r4.model.Observation; -import org.junit.*; +import org.junit.AfterClass; +import org.junit.BeforeClass; +import org.junit.Test; -import ca.uhn.fhir.context.*; -import ca.uhn.fhir.jpa.dao.ISearchParamRegistry; -import ca.uhn.fhir.jpa.entity.*; -import ca.uhn.fhir.util.TestUtil; +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import java.util.Set; + +import static org.junit.Assert.*; public class SearchParamExtractorR4Test { private static FhirContext ourCtx = FhirContext.forR4(); private static IValidationSupport ourValidationSupport; + @Test + public void testParamWithOrInPath() { + Observation obs = new Observation(); + obs.addCategory().addCoding().setSystem("SYSTEM").setCode("CODE"); + + ISearchParamRegistry searchParamRegistry = new ISearchParamRegistry() { + @Override + public void forceRefresh() { + // nothing + } + + @Override + public RuntimeSearchParam getActiveSearchParam(String theResourceName, String theParamName) { + throw new UnsupportedOperationException(); + } + + @Override + public Map> getActiveSearchParams() { + throw new UnsupportedOperationException(); + } + + @Override + public Map getActiveSearchParams(String theResourceName) { + RuntimeResourceDefinition nextResDef = ourCtx.getResourceDefinition(theResourceName); + Map sps = new HashMap<>(); + for (RuntimeSearchParam nextSp : nextResDef.getSearchParams()) { + sps.put(nextSp.getName(), nextSp); + } + return sps; + } + + @Override + public List getActiveUniqueSearchParams(String theResourceName, Set theParamNames) { + throw new UnsupportedOperationException(); + } + + @Override + public List getActiveUniqueSearchParams(String theResourceName) { + throw new UnsupportedOperationException(); + } + + @Override + public void refreshCacheIfNecessary() { + // nothing + } + + @Override + public void requestRefresh() { + // nothing + } + }; + + SearchParamExtractorR4 extractor = new SearchParamExtractorR4(ourCtx, ourValidationSupport, searchParamRegistry); + Set tokens = extractor.extractSearchParamTokens(new ResourceTable(), obs); + assertEquals(1, tokens.size()); + ResourceIndexedSearchParamToken token = (ResourceIndexedSearchParamToken) tokens.iterator().next(); + assertEquals("category", token.getParamName()); + assertEquals("SYSTEM", token.getSystem()); + assertEquals("CODE", token.getValue()); + } + @AfterClass public static void afterClassClearContext() { TestUtil.clearAllStaticFieldsForUnitTest(); @@ -29,56 +98,5 @@ public class SearchParamExtractorR4Test { public static void beforeClass() { ourValidationSupport = new DefaultProfileValidationSupport(); } - - @Test - public void testParamWithOrInPath() { - Observation obs = new Observation(); - obs.addCategory().addCoding().setSystem("SYSTEM").setCode("CODE"); - - ISearchParamRegistry searchParamRegistry = new ISearchParamRegistry() { - @Override - public Map getActiveSearchParams(String theResourceName) { - RuntimeResourceDefinition nextResDef = ourCtx.getResourceDefinition(theResourceName); - Map sps = new HashMap(); - for (RuntimeSearchParam nextSp : nextResDef.getSearchParams()) { - sps.put(nextSp.getName(), nextSp); - } - return sps; - } - @Override - public List getActiveUniqueSearchParams(String theResourceName) { - throw new UnsupportedOperationException(); - } - - @Override - public List getActiveUniqueSearchParams(String theResourceName, Set theParamNames) { - throw new UnsupportedOperationException(); - } - - @Override - public void forceRefresh() { - // nothing - } - - @Override - public Map> getActiveSearchParams() { - throw new UnsupportedOperationException(); - } - - @Override - public RuntimeSearchParam getActiveSearchParam(String theResourceName, String theParamName) { - throw new UnsupportedOperationException(); - } - }; - - SearchParamExtractorR4 extractor = new SearchParamExtractorR4(ourCtx, ourValidationSupport, searchParamRegistry); - Set tokens = extractor.extractSearchParamTokens(new ResourceTable(), obs); - assertEquals(1, tokens.size()); - ResourceIndexedSearchParamToken token = (ResourceIndexedSearchParamToken) tokens.iterator().next(); - assertEquals("category", token.getParamName()); - assertEquals("SYSTEM", token.getSystem()); - assertEquals("CODE", token.getValue()); - } - } diff --git a/hapi-fhir-jpaserver-base/src/test/java/ca/uhn/fhir/jpa/provider/dstu3/ResourceProviderCustomSearchParamDstu3Test.java b/hapi-fhir-jpaserver-base/src/test/java/ca/uhn/fhir/jpa/provider/dstu3/ResourceProviderCustomSearchParamDstu3Test.java index cbe670f717f..bd24e6ea298 100644 --- a/hapi-fhir-jpaserver-base/src/test/java/ca/uhn/fhir/jpa/provider/dstu3/ResourceProviderCustomSearchParamDstu3Test.java +++ b/hapi-fhir-jpaserver-base/src/test/java/ca/uhn/fhir/jpa/provider/dstu3/ResourceProviderCustomSearchParamDstu3Test.java @@ -306,7 +306,7 @@ public class ResourceProviderCustomSearchParamDstu3Test extends BaseResourceProv .resource(eyeColourSp) .execute(); - // mySearchParamRegsitry.forceRefresh(); + mySearchParamRegsitry.forceRefresh(); Patient p1 = new Patient(); p1.setActive(true); diff --git a/hapi-fhir-jpaserver-base/src/test/java/ca/uhn/fhir/jpa/provider/r4/ResourceProviderCustomSearchParamR4Test.java b/hapi-fhir-jpaserver-base/src/test/java/ca/uhn/fhir/jpa/provider/r4/ResourceProviderCustomSearchParamR4Test.java index 4ff7969e058..74db13cb895 100644 --- a/hapi-fhir-jpaserver-base/src/test/java/ca/uhn/fhir/jpa/provider/r4/ResourceProviderCustomSearchParamR4Test.java +++ b/hapi-fhir-jpaserver-base/src/test/java/ca/uhn/fhir/jpa/provider/r4/ResourceProviderCustomSearchParamR4Test.java @@ -306,7 +306,7 @@ public class ResourceProviderCustomSearchParamR4Test extends BaseResourceProvide .resource(eyeColourSp) .execute(); - // mySearchParamRegsitry.forceRefresh(); + mySearchParamRegsitry.forceRefresh(); Patient p1 = new Patient(); p1.setActive(true);