Support extensions pointing to references for JPA custom search params

This commit is contained in:
James Agnew 2017-04-14 07:26:49 -04:00
parent bf94d78872
commit 54055f5bfb
6 changed files with 80 additions and 15 deletions

View File

@ -195,6 +195,7 @@ public class DateRangeParam implements IQueryParameterAnd<DateParam> {
if (myLowerBound.getPrefix() != null) {
switch (myLowerBound.getPrefix()) {
case GREATERTHAN:
case STARTS_AFTER:
retVal = myLowerBound.getPrecision().add(retVal, 1);
break;
case EQUAL:
@ -205,7 +206,6 @@ public class DateRangeParam implements IQueryParameterAnd<DateParam> {
case LESSTHAN_OR_EQUALS:
case ENDS_BEFORE:
case NOT_EQUAL:
case STARTS_AFTER:
throw new IllegalStateException("Unvalid lower bound comparator: " + myLowerBound.getPrefix());
}
}
@ -224,6 +224,7 @@ public class DateRangeParam implements IQueryParameterAnd<DateParam> {
if (myUpperBound.getPrefix() != null) {
switch (myUpperBound.getPrefix()) {
case LESSTHAN:
case ENDS_BEFORE:
retVal = new Date(retVal.getTime() - 1L);
break;
case EQUAL:
@ -234,7 +235,6 @@ public class DateRangeParam implements IQueryParameterAnd<DateParam> {
case GREATERTHAN_OR_EQUALS:
case GREATERTHAN:
case APPROXIMATE:
case ENDS_BEFORE:
case NOT_EQUAL:
case STARTS_AFTER:
throw new IllegalStateException("Unvalid upper bound comparator: " + myUpperBound.getPrefix());

View File

@ -59,16 +59,7 @@ import org.apache.http.client.utils.URLEncodedUtils;
import org.hl7.fhir.dstu3.model.Bundle.HTTPVerb;
import org.hl7.fhir.dstu3.model.IdType;
import org.hl7.fhir.dstu3.model.StringType;
import org.hl7.fhir.instance.model.api.IAnyResource;
import org.hl7.fhir.instance.model.api.IBase;
import org.hl7.fhir.instance.model.api.IBaseBundle;
import org.hl7.fhir.instance.model.api.IBaseCoding;
import org.hl7.fhir.instance.model.api.IBaseOperationOutcome;
import org.hl7.fhir.instance.model.api.IBaseReference;
import org.hl7.fhir.instance.model.api.IBaseResource;
import org.hl7.fhir.instance.model.api.IDomainResource;
import org.hl7.fhir.instance.model.api.IIdType;
import org.hl7.fhir.instance.model.api.IPrimitiveType;
import org.hl7.fhir.instance.model.api.*;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.transaction.PlatformTransactionManager;
@ -262,8 +253,8 @@ public abstract class BaseHapiFhirDao<T extends IBaseResource> implements IDao {
return;
}
RuntimeResourceDefinition def = getContext().getResourceDefinition(theResource);
for (RuntimeSearchParam nextSpDef : def.getSearchParams()) {
Map<String, RuntimeSearchParam> searchParams = mySearchParamRegistry.getActiveSearchParams(toResourceName(theResource.getClass()));
for (RuntimeSearchParam nextSpDef : searchParams.values()) {
if (nextSpDef.getParamType() != RestSearchParameterTypeEnum.REFERENCE) {
continue;
@ -283,6 +274,14 @@ public abstract class BaseHapiFhirDao<T extends IBaseResource> implements IDao {
for (PathAndRef nextPathAndRef : refs) {
Object nextObject = nextPathAndRef.getRef();
/*
* A search parameter on an extension field that contains
* references should index those references
*/
if (nextObject instanceof IBaseExtension<?, ?>) {
nextObject = ((IBaseExtension<?, ?>) nextObject).getValue();
}
IIdType nextId;
if (nextObject instanceof IBaseReference) {
IBaseReference nextValue = (IBaseReference) nextObject;

View File

@ -93,7 +93,7 @@ public abstract class BaseSearchParamExtractor implements ISearchParamExtractor
return myContext;
}
protected Collection<RuntimeSearchParam> getSearchParams(IBaseResource theResource) {
public Collection<RuntimeSearchParam> getSearchParams(IBaseResource theResource) {
RuntimeResourceDefinition def = getContext().getResourceDefinition(theResource);
Collection<RuntimeSearchParam> retVal = mySearchParamRegistry.getActiveSearchParams(def.getName()).values();
List<RuntimeSearchParam> defaultList= Collections.emptyList();

View File

@ -6,6 +6,7 @@ import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertThat;
import static org.junit.Assert.fail;
import java.io.IOException;
import java.util.List;
import org.hl7.fhir.dstu3.model.CodeType;
@ -18,6 +19,9 @@ import org.junit.AfterClass;
import org.junit.Test;
import ca.uhn.fhir.jpa.dao.SearchParameterMap;
import ca.uhn.fhir.model.dstu.resource.Practitioner;
import ca.uhn.fhir.parser.DataFormatException;
import ca.uhn.fhir.rest.param.ReferenceParam;
import ca.uhn.fhir.rest.param.TokenParam;
import ca.uhn.fhir.rest.server.IBundleProvider;
import ca.uhn.fhir.rest.server.exceptions.UnprocessableEntityException;
@ -284,6 +288,34 @@ 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<String> ids = toUnqualifiedVersionlessIdValues(outcome);
ourLog.info("IDS: " + ids);
assertThat(ids, contains(pid.getValue()));
}
@AfterClass
public static void afterClassClearContext() {

View File

@ -0,0 +1,29 @@
{
"resourceType": "Patient",
"extension": [
{
"url": "http://fmcna.com/myDoctor",
"valueReference": {
"reference": "Practitioner/A"
}
}
],
"identifier": [{
"type": {
"coding": [{
"system": "http://hl7.org/fhir/v2/0203",
"code": "MR"
}]
},
"system": "http://hl7.org/fhir/v2/0203",
"value": "5000077430"
}],
"name": [{
"use": "official",
"family": "Ravi",
"given": [
"Kuchi"
]
}]
}

View File

@ -68,6 +68,11 @@
<![CDATA[<code>IFhirResourceDao#removeTag(IIdType, TagTypeEnum, String, String)</code>]]>. This allows client code to remove tags
from a resource without having a servlet request object in context.
</action>
<action type="fix">
JPA server was unable to process custom search parameters where
the path pointed to an extension containing a reference. Thanks
to Ravi Kuchi for reporting!
</action>
</release>
<release version="2.3" date="2017-03-18">
<action type="add">