Allow indexing in custom search params to descend into contained

resources
This commit is contained in:
James Agnew 2018-06-22 11:22:07 -04:00
parent e8c1e640d1
commit e9fffd3cdc
7 changed files with 5834 additions and 5511 deletions

View File

@ -64,7 +64,6 @@ public class FhirResourceDaoDstu3SearchCustomSearchParamTest extends BaseJpaDstu
}
}
@Test
public void testCreateInvalidParamNoPath() {
SearchParameter fooSp = new SearchParameter();
@ -858,6 +857,49 @@ public class FhirResourceDaoDstu3SearchCustomSearchParamTest extends BaseJpaDstu
}
@Test
public void testSearchParameterDescendsIntoContainedResource() {
SearchParameter sp = new SearchParameter();
sp.addBase("Observation");
sp.setCode("specimencollectedtime");
sp.setType(Enumerations.SearchParamType.DATE);
sp.setTitle("Observation Specimen Collected Time");
sp.setExpression("Observation.specimen.resolve().receivedTime");
sp.setXpathUsage(SearchParameter.XPathUsageType.NORMAL);
sp.setStatus(Enumerations.PublicationStatus.ACTIVE);
ourLog.info(myFhirCtx.newJsonParser().setPrettyPrint(true).encodeResourceToString(sp));
mySearchParameterDao.create(sp);
mySearchParamRegsitry.forceRefresh();
Specimen specimen = new Specimen();
specimen.setId("#FOO");
specimen.setReceivedTimeElement(new DateTimeType("2011-01-01"));
Observation o = new Observation();
o.setId("O1");
o.getContained().add(specimen);
o.setStatus(Observation.ObservationStatus.FINAL);
o.setSpecimen(new Reference("#FOO"));
myObservationDao.update(o);
specimen = new Specimen();
specimen.setId("#FOO");
specimen.setReceivedTimeElement(new DateTimeType("2011-01-03"));
o = new Observation();
o.setId("O2");
o.getContained().add(specimen);
o.setStatus(Observation.ObservationStatus.FINAL);
o.setSpecimen(new Reference("#FOO"));
myObservationDao.update(o);
SearchParameterMap params = new SearchParameterMap();
params.add("specimencollectedtime", new DateParam("2011-01-01"));
IBundleProvider outcome = myObservationDao.search(params);
List<String> ids = toUnqualifiedVersionlessIdValues(outcome);
ourLog.info("IDS: " + ids);
assertThat(ids, contains("Observation/O1"));
}
@Test
public void testSearchWithCustomParam() {

View File

@ -128,7 +128,7 @@ public class FhirResourceDaoR4SearchCustomSearchParamTest extends BaseJpaR4Test
}
@Test
public void testCreateSearchParameterOnSearchParameterDoesntCauseEndlessReindexLoop() throws InterruptedException {
public void testCreateSearchParameterOnSearchParameterDoesntCauseEndlessReindexLoop() {
SearchParameter fooSp = new SearchParameter();
fooSp.setCode("foo");
fooSp.addBase("SearchParameter");
@ -175,6 +175,48 @@ public class FhirResourceDaoR4SearchCustomSearchParamTest extends BaseJpaR4Test
assertThat(ids, contains(pid.getValue()));
}
@Test
public void testSearchParameterDescendsIntoContainedResource() {
SearchParameter sp = new SearchParameter();
sp.addBase("Observation");
sp.setCode("specimencollectedtime");
sp.setType(Enumerations.SearchParamType.DATE);
sp.setTitle("Observation Specimen Collected Time");
sp.setExpression("Observation.specimen.resolve().receivedTime");
sp.setXpathUsage(org.hl7.fhir.r4.model.SearchParameter.XPathUsageType.NORMAL);
sp.setStatus(org.hl7.fhir.r4.model.Enumerations.PublicationStatus.ACTIVE);
mySearchParameterDao.create(sp);
mySearchParamRegsitry.forceRefresh();
Specimen specimen = new Specimen();
specimen.setId("#FOO");
specimen.setReceivedTimeElement(new DateTimeType("2011-01-01"));
Observation o = new Observation();
o.setId("O1");
o.getContained().add(specimen);
o.setStatus(Observation.ObservationStatus.FINAL);
o.setSpecimen(new Reference("#FOO"));
myObservationDao.update(o);
specimen = new Specimen();
specimen.setId("#FOO");
specimen.setReceivedTimeElement(new DateTimeType("2011-01-03"));
o = new Observation();
o.setId("O2");
o.getContained().add(specimen);
o.setStatus(Observation.ObservationStatus.FINAL);
o.setSpecimen(new Reference("#FOO"));
myObservationDao.update(o);
SearchParameterMap params = new SearchParameterMap();
params.add("specimencollectedtime", new DateParam("2011-01-01"));
IBundleProvider outcome = myObservationDao.search(params);
List<String> ids = toUnqualifiedVersionlessIdValues(outcome);
ourLog.info("IDS: " + ids);
assertThat(ids, contains("Observation/O1"));
}
@Test
public void testExtensionWithNoValueIndexesWithoutFailure() {
SearchParameter eyeColourSp = new SearchParameter();

View File

@ -1,45 +1,59 @@
package org.hl7.fhir.dstu3.utils;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertTrue;
import java.util.List;
import org.hl7.fhir.exceptions.FHIRException;
import org.hl7.fhir.dstu3.hapi.validation.DefaultProfileValidationSupport;
import ca.uhn.fhir.context.FhirContext;
import ca.uhn.fhir.util.TestUtil;
import org.hl7.fhir.dstu3.hapi.ctx.HapiWorkerContext;
import org.hl7.fhir.dstu3.hapi.validation.DefaultProfileValidationSupport;
import org.hl7.fhir.dstu3.model.*;
import org.hl7.fhir.exceptions.FHIRException;
import org.junit.AfterClass;
import org.junit.BeforeClass;
import org.junit.Test;
import ca.uhn.fhir.context.FhirContext;
import ca.uhn.fhir.util.TestUtil;
import java.util.List;
import static org.junit.Assert.*;
public class FhirPathEngineTest {
private static final org.slf4j.Logger ourLog = org.slf4j.LoggerFactory.getLogger(FhirPathEngineTest.class);
private static FhirContext ourCtx = FhirContext.forDstu3();
private static FHIRPathEngine ourEngine;
private static final org.slf4j.Logger ourLog = org.slf4j.LoggerFactory.getLogger(FhirPathEngineTest.class);
@Test
public void testAs() throws Exception {
Observation obs = new Observation();
obs.setValue(new StringType("FOO"));
List<Base> value = ourEngine.evaluate(obs, "Observation.value.as(String)");
assertEquals(1, value.size());
assertEquals("FOO", ((StringType)value.get(0)).getValue());
assertEquals("FOO", ((StringType) value.get(0)).getValue());
}
@Test
public void testCrossResourceBoundaries() throws FHIRException {
Specimen specimen = new Specimen();
specimen.setId("#FOO");
specimen.setReceivedTimeElement(new DateTimeType("2011-01-01"));
Observation o = new Observation();
o.getContained().add(specimen);
o.setId("O1");
o.setStatus(Observation.ObservationStatus.FINAL);
o.setSpecimen(new Reference("#FOO"));
List<Base> value = ourEngine.evaluate(o, "Observation.specimen.resolve().receivedTime");
assertEquals(1, value.size());
assertEquals("2011-01-01", ((DateTimeType) value.get(0)).getValueAsString());
}
@Test
public void testExistsWithNoValue() throws FHIRException {
Patient patient = new Patient();
patient.setDeceased(new BooleanType());
List<Base> eval = ourEngine.evaluate(patient, "Patient.deceased.exists()");
ourLog.info(eval.toString());
assertFalse(((BooleanType)eval.get(0)).getValue());
assertFalse(((BooleanType) eval.get(0)).getValue());
}
@Test
@ -48,7 +62,7 @@ public class FhirPathEngineTest {
patient.setDeceased(new BooleanType(false));
List<Base> eval = ourEngine.evaluate(patient, "Patient.deceased.exists()");
ourLog.info(eval.toString());
assertTrue(((BooleanType)eval.get(0)).getValue());
assertTrue(((BooleanType) eval.get(0)).getValue());
}
@AfterClass

View File

@ -3,14 +3,12 @@ package org.hl7.fhir.r4.utils;
import ca.uhn.fhir.context.FhirContext;
import ca.uhn.fhir.util.TestUtil;
import org.hl7.fhir.dstu3.utils.FhirPathEngineTest;
import org.hl7.fhir.exceptions.FHIRException;
import org.hl7.fhir.r4.hapi.ctx.DefaultProfileValidationSupport;
import org.hl7.fhir.r4.hapi.ctx.HapiWorkerContext;
import org.hl7.fhir.r4.model.*;
import org.hl7.fhir.r4.utils.FHIRPathEngine;
import org.hl7.fhir.exceptions.FHIRException;
import org.junit.AfterClass;
import org.junit.BeforeClass;
import org.junit.Ignore;
import org.junit.Test;
import java.util.List;
@ -23,6 +21,23 @@ public class FhirPathEngineR4Test {
private static FHIRPathEngine ourEngine;
private static final org.slf4j.Logger ourLog = org.slf4j.LoggerFactory.getLogger(FhirPathEngineTest.class);
@Test
public void testCrossResourceBoundaries() throws FHIRException {
Specimen specimen = new Specimen();
specimen.setId("#FOO");
specimen.setReceivedTimeElement(new DateTimeType("2011-01-01"));
Observation o = new Observation();
o.getContained().add(specimen);
o.setId("O1");
o.setStatus(Observation.ObservationStatus.FINAL);
o.setSpecimen(new Reference("#FOO"));
List<Base> value = ourEngine.evaluate(o, "Observation.specimen.resolve().receivedTime");
assertEquals(1, value.size());
assertEquals("2011-01-01", ((DateTimeType) value.get(0)).getValueAsString());
}
@Test
public void testAs() throws Exception {
Observation obs = new Observation();

View File

@ -76,6 +76,12 @@
scheme introduced in LOINC 2.64. Thanks to Rob Hausam for the
pull request!
</action>
<action type="add">
In the JPA server, it is now possible for a custom search parameter
to use the
<![CDATA[<code>resolve()</code>]]> function in its path to descend into
contained resources and index fields within them.
</action>
</release>
<release version="3.4.0" date="2018-05-28">
<action type="add">