Reuse FHIRPath across JPA requests

This commit is contained in:
James Agnew 2019-08-29 14:13:31 -04:00
parent c5a88444b6
commit f59bdc4afe
3 changed files with 25 additions and 10 deletions

View File

@ -39,6 +39,7 @@ import org.hl7.fhir.instance.model.api.IBase;
import org.hl7.fhir.instance.model.api.IBaseResource;
import org.hl7.fhir.instance.model.api.IPrimitiveType;
import org.hl7.fhir.r4.context.IWorkerContext;
import org.hl7.fhir.r4.hapi.ctx.HapiWorkerContext;
import org.hl7.fhir.r4.hapi.ctx.IValidationSupport;
import org.hl7.fhir.r4.model.*;
import org.hl7.fhir.r4.model.Enumeration;
@ -48,6 +49,7 @@ import org.hl7.fhir.r4.model.Patient.PatientCommunicationComponent;
import org.hl7.fhir.r4.utils.FHIRPathEngine;
import org.springframework.beans.factory.annotation.Autowired;
import javax.annotation.PostConstruct;
import javax.measure.unit.NonSI;
import javax.measure.unit.Unit;
import java.math.BigDecimal;
@ -79,6 +81,8 @@ public class SearchParamExtractorR4 extends BaseSearchParamExtractor implements
@Autowired
private org.hl7.fhir.r4.hapi.ctx.IValidationSupport myValidationSupport;
private FHIRPathEngine myFhirPathEngine;
/**
* Constructor
*/
@ -91,6 +95,14 @@ public class SearchParamExtractorR4 extends BaseSearchParamExtractor implements
public SearchParamExtractorR4(ModelConfig theModelConfig, FhirContext theCtx, IValidationSupport theValidationSupport, ISearchParamRegistry theSearchParamRegistry) {
super(theCtx, theSearchParamRegistry);
myValidationSupport = theValidationSupport;
initFhirPath();
}
@PostConstruct
public void initFhirPath() {
IWorkerContext worker = new HapiWorkerContext(getContext(), myValidationSupport);
myFhirPathEngine = new FHIRPathEngine(worker);
myFhirPathEngine.setHostServices(new SearchParamExtractorR4HostServices());
}
private void addQuantity(ResourceTable theEntity, HashSet<ResourceIndexedSearchParamQuantity> retVal, String resourceName, Quantity nextValue) {
@ -751,16 +763,12 @@ public class SearchParamExtractorR4 extends BaseSearchParamExtractor implements
*/
@Override
protected List<Object> extractValues(String thePaths, IBaseResource theResource) {
IWorkerContext worker = new org.hl7.fhir.r4.hapi.ctx.HapiWorkerContext(getContext(), myValidationSupport);
FHIRPathEngine fp = new FHIRPathEngine(worker);
fp.setHostServices(new SearchParamExtractorR4HostServices());
List<Object> values = new ArrayList<>();
String[] nextPathsSplit = SPLIT_R4.split(thePaths);
for (String nextPath : nextPathsSplit) {
List<Base> allValues;
try {
allValues = fp.evaluate((Base) theResource, nextPath);
allValues = myFhirPathEngine.evaluate((Base) theResource, nextPath);
} catch (FHIRException e) {
String msg = getContext().getLocalizer().getMessage(BaseSearchParamExtractor.class, "failedToExtractPaths", nextPath, e.toString());
throw new InternalErrorException(msg, e);

View File

@ -39,6 +39,7 @@ import org.hl7.fhir.instance.model.api.IBase;
import org.hl7.fhir.instance.model.api.IBaseResource;
import org.hl7.fhir.instance.model.api.IPrimitiveType;
import org.hl7.fhir.r5.context.IWorkerContext;
import org.hl7.fhir.r5.hapi.ctx.HapiWorkerContext;
import org.hl7.fhir.r5.hapi.ctx.IValidationSupport;
import org.hl7.fhir.r5.model.*;
import org.hl7.fhir.r5.model.Enumeration;
@ -48,6 +49,7 @@ import org.hl7.fhir.r5.model.Patient.PatientCommunicationComponent;
import org.hl7.fhir.r5.utils.FHIRPathEngine;
import org.springframework.beans.factory.annotation.Autowired;
import javax.annotation.PostConstruct;
import javax.measure.unit.NonSI;
import javax.measure.unit.Unit;
import java.math.BigDecimal;
@ -78,6 +80,7 @@ public class SearchParamExtractorR5 extends BaseSearchParamExtractor implements
@Autowired
private IValidationSupport myValidationSupport;
private FHIRPathEngine myFhirPathEngine;
/**
* Constructor
@ -86,11 +89,11 @@ public class SearchParamExtractorR5 extends BaseSearchParamExtractor implements
super();
}
// This constructor is used by tests
@VisibleForTesting
public SearchParamExtractorR5(ModelConfig theModelConfig, FhirContext theCtx, IValidationSupport theValidationSupport, ISearchParamRegistry theSearchParamRegistry) {
super(theCtx, theSearchParamRegistry);
myValidationSupport = theValidationSupport;
@PostConstruct
public void initFhirPath() {
IWorkerContext worker = new HapiWorkerContext(getContext(), myValidationSupport);
myFhirPathEngine = new FHIRPathEngine(worker);
myFhirPathEngine.setHostServices(new SearchParamExtractorR5HostServices());
}
private void addQuantity(ResourceTable theEntity, HashSet<ResourceIndexedSearchParamQuantity> retVal, String resourceName, Quantity nextValue) {

View File

@ -78,6 +78,10 @@
checker. This regex was causing a noticable performance drop when feeding large numbers of transactions
into the JPA server at the same time (i.e. when loading Synthea data).
</action>
<action type="fix">
The FHIRPath engine used to parse search parameters in the JPA R4/R5 server is now reused across
requests, as it is somewhat expensive to create and is thread safe.
</action>
<action type="add">
It is now possible to submit a PATCH request as a part of a FHIR transaction in DSTU3 (previously this
was only supported in R4+). This is not officially part of the DSTU3 spec, but it can now be performed by