Merge commit 'af5c45531ab59c1374cd99230bd5b8e32c692123' into mb-20210203-date-param-validation
This commit is contained in:
commit
eee11c8844
|
@ -33,15 +33,15 @@ public class FhirClientConnectionException extends BaseServerResponseException {
|
|||
private static final long serialVersionUID = 1L;
|
||||
|
||||
public FhirClientConnectionException(Throwable theCause) {
|
||||
super(0, theCause);
|
||||
super(500, theCause);
|
||||
}
|
||||
|
||||
public FhirClientConnectionException(String theMessage, Throwable theCause) {
|
||||
super(0, theMessage, theCause);
|
||||
super(500, theMessage, theCause);
|
||||
}
|
||||
|
||||
public FhirClientConnectionException(String theMessage) {
|
||||
super(0, theMessage);
|
||||
super(500, theMessage);
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -233,7 +233,7 @@ public class BundleUtil {
|
|||
* All 3 might be null - That's ok because we still want to know the
|
||||
* order in the original bundle.
|
||||
*/
|
||||
BundleEntryMutator mutator = new BundleEntryMutator(nextEntry, requestChildDef, requestChildContentsDef);
|
||||
BundleEntryMutator mutator = new BundleEntryMutator(theContext, nextEntry, requestChildDef, requestChildContentsDef, entryChildContentsDef);
|
||||
ModifiableBundleEntry entry = new ModifiableBundleEntry(new BundleEntryParts(fullUrl, requestType, url, resource, conditionalUrl), mutator);
|
||||
theProcessor.accept(entry);
|
||||
}
|
||||
|
|
|
@ -31,11 +31,15 @@ public class BundleEntryMutator {
|
|||
private final IBase myEntry;
|
||||
private final BaseRuntimeChildDefinition myRequestChildDef;
|
||||
private final BaseRuntimeElementCompositeDefinition<?> myRequestChildContentsDef;
|
||||
private final FhirContext myFhirContext;
|
||||
private final BaseRuntimeElementCompositeDefinition<?> myEntryDefinition;
|
||||
|
||||
public BundleEntryMutator(IBase theEntry, BaseRuntimeChildDefinition theRequestChildDef, BaseRuntimeElementCompositeDefinition<?> theRequestChildContentsDef) {
|
||||
public BundleEntryMutator(FhirContext theFhirContext, IBase theEntry, BaseRuntimeChildDefinition theRequestChildDef, BaseRuntimeElementCompositeDefinition<?> theChildContentsDef, BaseRuntimeElementCompositeDefinition<?> theEntryDefinition) {
|
||||
myFhirContext = theFhirContext;
|
||||
myEntry = theEntry;
|
||||
myRequestChildDef = theRequestChildDef;
|
||||
myRequestChildContentsDef = theRequestChildContentsDef;
|
||||
myRequestChildContentsDef = theChildContentsDef;
|
||||
myEntryDefinition = theEntryDefinition;
|
||||
}
|
||||
|
||||
void setRequestUrl(FhirContext theFhirContext, String theRequestUrl) {
|
||||
|
@ -45,4 +49,13 @@ public class BundleEntryMutator {
|
|||
requestUrlChildDef.getMutator().addValue(nextRequest, url);
|
||||
}
|
||||
}
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
public void setFullUrl(String theFullUrl) {
|
||||
IPrimitiveType<String> value = (IPrimitiveType<String>) myFhirContext.getElementDefinition("uri").newInstance();
|
||||
value.setValue(theFullUrl);
|
||||
|
||||
BaseRuntimeChildDefinition fullUrlChild = myEntryDefinition.getChildByName("fullUrl");
|
||||
fullUrlChild.getMutator().setValue(myEntry, value);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -58,4 +58,5 @@ public class BundleEntryParts {
|
|||
public String getUrl() {
|
||||
return myUrl;
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -51,4 +51,8 @@ public class ModifiableBundleEntry {
|
|||
public IBaseResource getResource() {
|
||||
return myBundleEntryParts.getResource();
|
||||
}
|
||||
|
||||
public void setFullUrl(String theFullUrl) {
|
||||
myBundleEntryMutator.setFullUrl(theFullUrl);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -24,6 +24,7 @@ import com.fasterxml.jackson.core.JsonGenerator;
|
|||
import com.fasterxml.jackson.databind.ObjectMapper;
|
||||
import com.fasterxml.jackson.databind.SerializationFeature;
|
||||
import org.hl7.fhir.r4.model.Observation;
|
||||
import org.junit.jupiter.api.AfterEach;
|
||||
import org.junit.jupiter.api.BeforeAll;
|
||||
import org.junit.jupiter.api.BeforeEach;
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
@ -93,6 +94,11 @@ public class LastNElasticsearchSvcMultipleObservationsIT {
|
|||
}
|
||||
}
|
||||
|
||||
@AfterEach
|
||||
public void after() throws IOException {
|
||||
elasticsearchSvc.close();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testLastNAllPatientsQuery() {
|
||||
|
||||
|
|
|
@ -28,45 +28,6 @@
|
|||
<artifactId>evaluator.engine</artifactId>
|
||||
<version>${cql-evaluator.version}</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.opencds.cqf</groupId>
|
||||
<artifactId>tooling</artifactId>
|
||||
<version>${cqf-tooling.version}</version>
|
||||
<exclusions>
|
||||
<exclusion>
|
||||
<groupId>org.slf4j</groupId>
|
||||
<artifactId>slf4j-log4j12</artifactId>
|
||||
</exclusion>
|
||||
<exclusion>
|
||||
<groupId>javax.activation</groupId>
|
||||
<artifactId>javax.activation-api</artifactId>
|
||||
</exclusion>
|
||||
<exclusion>
|
||||
<groupId>javax.xml.bind</groupId>
|
||||
<artifactId>jaxb-api</artifactId>
|
||||
</exclusion>
|
||||
<exclusion>
|
||||
<groupId>jakarta.xml.bind</groupId>
|
||||
<artifactId>jakarta.xml.bind-api</artifactId>
|
||||
</exclusion>
|
||||
<exclusion>
|
||||
<groupId>jakarta.xml.bind</groupId>
|
||||
<artifactId>jaxb-api</artifactId>
|
||||
</exclusion>
|
||||
<exclusion>
|
||||
<groupId>com.sun.istack</groupId>
|
||||
<artifactId>istack-commons-tools</artifactId>
|
||||
</exclusion>
|
||||
<exclusion>
|
||||
<groupId>com.sun.istack</groupId>
|
||||
<artifactId>istack-commons-runtime</artifactId>
|
||||
</exclusion>
|
||||
<exclusion>
|
||||
<groupId>info.bliki.wiki</groupId>
|
||||
<artifactId>bliki-core</artifactId>
|
||||
</exclusion>
|
||||
</exclusions>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.opencds.cqf.cql</groupId>
|
||||
<artifactId>engine</artifactId>
|
||||
|
@ -108,6 +69,21 @@
|
|||
</exclusion>
|
||||
</exclusions>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>info.cqframework</groupId>
|
||||
<artifactId>quick</artifactId>
|
||||
<version>${cqframework.version}</version>
|
||||
<exclusions>
|
||||
<exclusion>
|
||||
<groupId>jakarta.xml.bind</groupId>
|
||||
<artifactId>jaxb-api</artifactId>
|
||||
</exclusion>
|
||||
<exclusion>
|
||||
<groupId>jakarta.xml.bind</groupId>
|
||||
<artifactId>jakarta.xml.bind-api</artifactId>
|
||||
</exclusion>
|
||||
</exclusions>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>javax.xml.bind</groupId>
|
||||
<artifactId>jaxb-api</artifactId>
|
||||
|
|
|
@ -30,7 +30,6 @@ import ca.uhn.fhir.cql.dstu3.provider.JpaTerminologyProvider;
|
|||
import ca.uhn.fhir.cql.dstu3.provider.LibraryResolutionProviderImpl;
|
||||
import ca.uhn.fhir.cql.dstu3.provider.MeasureOperationsProvider;
|
||||
import ca.uhn.fhir.jpa.api.dao.DaoRegistry;
|
||||
import ca.uhn.fhir.jpa.rp.dstu3.ValueSetResourceProvider;
|
||||
import ca.uhn.fhir.jpa.term.api.ITermReadSvcDstu3;
|
||||
|
||||
import org.opencds.cqf.cql.engine.model.ModelResolver;
|
||||
|
@ -39,6 +38,7 @@ import java.util.Map;
|
|||
|
||||
import org.cqframework.cql.cql2elm.model.Model;
|
||||
import org.hl7.elm.r1.VersionedIdentifier;
|
||||
import org.hl7.fhir.dstu3.model.ValueSet;
|
||||
import org.opencds.cqf.cql.engine.fhir.model.Dstu3FhirModelResolver;
|
||||
import org.opencds.cqf.cql.engine.terminology.TerminologyProvider;
|
||||
import org.opencds.cqf.cql.evaluator.engine.model.CachingModelResolverDecorator;
|
||||
|
@ -50,14 +50,16 @@ import org.springframework.context.annotation.Lazy;
|
|||
public class CqlDstu3Config extends BaseCqlConfig {
|
||||
@Lazy
|
||||
@Bean
|
||||
TerminologyProvider terminologyProvider(ITermReadSvcDstu3 theITermReadSvc,
|
||||
ValueSetResourceProvider theValueSetResourceProvider, IValidationSupport theValidationSupport) {
|
||||
return new JpaTerminologyProvider(theITermReadSvc, theValueSetResourceProvider, theValidationSupport);
|
||||
TerminologyProvider terminologyProvider(ITermReadSvcDstu3 theITermReadSvc, DaoRegistry daoRegistry,
|
||||
IValidationSupport theValidationSupport) {
|
||||
return new JpaTerminologyProvider(theITermReadSvc, daoRegistry.getResourceDao(ValueSet.class),
|
||||
theValidationSupport);
|
||||
}
|
||||
|
||||
@Lazy
|
||||
@Bean
|
||||
EvaluationProviderFactory evaluationProviderFactory(FhirContext theFhirContext, DaoRegistry theDaoRegistry, TerminologyProvider theLocalSystemTerminologyProvider, ModelResolver modelResolver) {
|
||||
EvaluationProviderFactory evaluationProviderFactory(FhirContext theFhirContext, DaoRegistry theDaoRegistry,
|
||||
TerminologyProvider theLocalSystemTerminologyProvider, ModelResolver modelResolver) {
|
||||
return new ProviderFactory(theFhirContext, theDaoRegistry, theLocalSystemTerminologyProvider, modelResolver);
|
||||
}
|
||||
|
||||
|
@ -66,7 +68,7 @@ public class CqlDstu3Config extends BaseCqlConfig {
|
|||
LibraryResolutionProvider libraryResolutionProvider() {
|
||||
return new LibraryResolutionProviderImpl();
|
||||
}
|
||||
|
||||
|
||||
@Lazy
|
||||
@Bean
|
||||
public MeasureOperationsProvider measureOperationsProvider() {
|
||||
|
@ -74,7 +76,7 @@ public class CqlDstu3Config extends BaseCqlConfig {
|
|||
}
|
||||
|
||||
@Bean
|
||||
public ModelResolver fhirModelResolver () {
|
||||
public ModelResolver fhirModelResolver() {
|
||||
return new CachingModelResolverDecorator(new Dstu3FhirModelResolver());
|
||||
}
|
||||
|
||||
|
|
|
@ -31,7 +31,6 @@ import ca.uhn.fhir.cql.r4.helper.LibraryHelper;
|
|||
import ca.uhn.fhir.cql.r4.provider.JpaTerminologyProvider;
|
||||
import ca.uhn.fhir.cql.r4.provider.MeasureOperationsProvider;
|
||||
import ca.uhn.fhir.jpa.api.dao.DaoRegistry;
|
||||
import ca.uhn.fhir.jpa.rp.r4.ValueSetResourceProvider;
|
||||
import ca.uhn.fhir.jpa.term.api.ITermReadSvcR4;
|
||||
|
||||
import org.opencds.cqf.cql.engine.model.ModelResolver;
|
||||
|
@ -40,6 +39,7 @@ import java.util.Map;
|
|||
|
||||
import org.cqframework.cql.cql2elm.model.Model;
|
||||
import org.hl7.elm.r1.VersionedIdentifier;
|
||||
import org.hl7.fhir.r4.model.ValueSet;
|
||||
import org.opencds.cqf.cql.engine.fhir.model.R4FhirModelResolver;
|
||||
import org.opencds.cqf.cql.engine.terminology.TerminologyProvider;
|
||||
import org.opencds.cqf.cql.evaluator.engine.model.CachingModelResolverDecorator;
|
||||
|
@ -58,13 +58,15 @@ public class CqlR4Config extends BaseCqlConfig {
|
|||
|
||||
@Lazy
|
||||
@Bean
|
||||
TerminologyProvider terminologyProvider(ITermReadSvcR4 theITermReadSvc, ValueSetResourceProvider theValueSetResourceProvider, IValidationSupport theValidationSupport) {
|
||||
return new JpaTerminologyProvider(theITermReadSvc,theValueSetResourceProvider, theValidationSupport);
|
||||
TerminologyProvider terminologyProvider(ITermReadSvcR4 theITermReadSvc, DaoRegistry daoRegistry,
|
||||
IValidationSupport theValidationSupport) {
|
||||
return new JpaTerminologyProvider(theITermReadSvc, daoRegistry.getResourceDao(ValueSet.class), theValidationSupport);
|
||||
}
|
||||
|
||||
@Lazy
|
||||
@Bean
|
||||
EvaluationProviderFactory evaluationProviderFactory(FhirContext theFhirContext, DaoRegistry theDaoRegistry, TerminologyProvider theLocalSystemTerminologyProvider, ModelResolver modelResolver) {
|
||||
EvaluationProviderFactory evaluationProviderFactory(FhirContext theFhirContext, DaoRegistry theDaoRegistry,
|
||||
TerminologyProvider theLocalSystemTerminologyProvider, ModelResolver modelResolver) {
|
||||
return new ProviderFactory(theFhirContext, theDaoRegistry, theLocalSystemTerminologyProvider, modelResolver);
|
||||
}
|
||||
|
||||
|
@ -81,7 +83,7 @@ public class CqlR4Config extends BaseCqlConfig {
|
|||
}
|
||||
|
||||
@Bean
|
||||
public ModelResolver fhirModelResolver () {
|
||||
public ModelResolver fhirModelResolver() {
|
||||
return new CachingModelResolverDecorator(new R4FhirModelResolver());
|
||||
}
|
||||
|
||||
|
|
|
@ -20,12 +20,10 @@ package ca.uhn.fhir.cql.dstu3.provider;
|
|||
* #L%
|
||||
*/
|
||||
|
||||
import ca.uhn.fhir.context.FhirContext;
|
||||
import ca.uhn.fhir.context.support.IValidationSupport;
|
||||
import ca.uhn.fhir.context.support.IValidationSupport.LookupCodeResult;
|
||||
import ca.uhn.fhir.context.support.ValidationSupportContext;
|
||||
import ca.uhn.fhir.context.support.ValueSetExpansionOptions;
|
||||
import ca.uhn.fhir.jpa.rp.dstu3.ValueSetResourceProvider;
|
||||
import ca.uhn.fhir.jpa.api.dao.IFhirResourceDao;
|
||||
import ca.uhn.fhir.jpa.searchparam.SearchParameterMap;
|
||||
import ca.uhn.fhir.jpa.term.api.ITermReadSvcDstu3;
|
||||
|
@ -34,7 +32,6 @@ import ca.uhn.fhir.rest.param.UriParam;
|
|||
import ca.uhn.fhir.rest.server.exceptions.ResourceNotFoundException;
|
||||
import org.hl7.fhir.dstu3.model.IdType;
|
||||
import org.hl7.fhir.dstu3.model.ValueSet;
|
||||
import org.hl7.fhir.dstu3.model.ValueSet.ValueSetExpansionContainsComponent;
|
||||
import org.hl7.fhir.instance.model.api.IBaseResource;
|
||||
import org.opencds.cqf.cql.engine.runtime.Code;
|
||||
import org.opencds.cqf.cql.engine.terminology.CodeSystemInfo;
|
||||
|
@ -53,14 +50,14 @@ import java.util.List;
|
|||
public class JpaTerminologyProvider implements TerminologyProvider {
|
||||
|
||||
private ITermReadSvcDstu3 terminologySvc;
|
||||
private ValueSetResourceProvider valueSetResourceProvider;
|
||||
private IFhirResourceDao<ValueSet> valueSetDao;
|
||||
private final IValidationSupport validationSupport;
|
||||
|
||||
@Autowired
|
||||
public JpaTerminologyProvider(ITermReadSvcDstu3 terminologySvc,
|
||||
ValueSetResourceProvider valueSetResourceProvider, IValidationSupport validationSupport) {
|
||||
IFhirResourceDao<ValueSet> valueSetDao, IValidationSupport validationSupport) {
|
||||
this.terminologySvc = terminologySvc;
|
||||
this.valueSetResourceProvider = valueSetResourceProvider;
|
||||
this.valueSetDao = valueSetDao;
|
||||
this.validationSupport = validationSupport;
|
||||
}
|
||||
|
||||
|
@ -78,9 +75,8 @@ public class JpaTerminologyProvider implements TerminologyProvider {
|
|||
|
||||
@Override
|
||||
public Iterable<Code> expand(ValueSetInfo valueSet) throws ResourceNotFoundException {
|
||||
List<Code> codes = new ArrayList<>();
|
||||
boolean needsExpand = false;
|
||||
ValueSet vs = null;
|
||||
// This could possibly be refactored into a single call to the underlying HAPI Terminology service. Need to think through that..,
|
||||
ValueSet vs;
|
||||
if (valueSet.getId().startsWith("http://") || valueSet.getId().startsWith("https://")) {
|
||||
if (valueSet.getVersion() != null
|
||||
|| (valueSet.getCodeSystems() != null && valueSet.getCodeSystems().size() > 0)) {
|
||||
|
@ -90,7 +86,8 @@ public class JpaTerminologyProvider implements TerminologyProvider {
|
|||
valueSet.getId()));
|
||||
}
|
||||
}
|
||||
IBundleProvider bundleProvider = valueSetResourceProvider.getDao()
|
||||
|
||||
IBundleProvider bundleProvider = this.valueSetDao
|
||||
.search(new SearchParameterMap().add(ValueSet.SP_URL, new UriParam(valueSet.getId())));
|
||||
List<IBaseResource> valueSets = bundleProvider.getResources(0, bundleProvider.size());
|
||||
if (valueSets.isEmpty()) {
|
||||
|
@ -101,41 +98,37 @@ public class JpaTerminologyProvider implements TerminologyProvider {
|
|||
throw new IllegalArgumentException("Found more than 1 ValueSet with url: " + valueSet.getId());
|
||||
}
|
||||
} else {
|
||||
vs = valueSetResourceProvider.getDao().read(new IdType(valueSet.getId()));
|
||||
}
|
||||
if (vs != null) {
|
||||
if (vs.hasCompose()) {
|
||||
if (vs.getCompose().hasInclude()) {
|
||||
for (ValueSet.ConceptSetComponent include : vs.getCompose().getInclude()) {
|
||||
if (include.hasValueSet() || include.hasFilter()) {
|
||||
needsExpand = true;
|
||||
break;
|
||||
}
|
||||
for (ValueSet.ConceptReferenceComponent concept : include.getConcept()) {
|
||||
if (concept.hasCode()) {
|
||||
codes.add(new Code().withCode(concept.getCode()).withSystem(include.getSystem()));
|
||||
}
|
||||
}
|
||||
}
|
||||
if (!needsExpand) {
|
||||
return codes;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (vs.hasExpansion() && vs.getExpansion().hasContains()) {
|
||||
for (ValueSetExpansionContainsComponent vsecc : vs.getExpansion().getContains()) {
|
||||
codes.add(new Code().withCode(vsecc.getCode()).withSystem(vsecc.getSystem()));
|
||||
}
|
||||
|
||||
return codes;
|
||||
vs = this.valueSetDao.read(new IdType(valueSet.getId()));
|
||||
if (vs == null) {
|
||||
throw new IllegalArgumentException(String.format("Could not resolve value set %s.", valueSet.getId()));
|
||||
}
|
||||
}
|
||||
|
||||
org.hl7.fhir.r4.model.ValueSet expansion = terminologySvc
|
||||
.expandValueSet(new ValueSetExpansionOptions().setCount(Integer.MAX_VALUE), valueSet.getId(), null);
|
||||
expansion.getExpansion().getContains()
|
||||
.forEach(concept -> codes.add(new Code().withCode(concept.getCode()).withSystem(concept.getSystem())));
|
||||
// Attempt to expand the ValueSet if it's not already expanded.
|
||||
if (!(vs.hasExpansion() && vs.getExpansion().hasContains())) {
|
||||
vs = (ValueSet)this.terminologySvc.expandValueSet(
|
||||
new ValueSetExpansionOptions().setCount(Integer.MAX_VALUE).setFailOnMissingCodeSystem(false), vs);
|
||||
}
|
||||
|
||||
List<Code> codes = new ArrayList<>();
|
||||
|
||||
// If expansion was successful, use the codes.
|
||||
if (vs.hasExpansion() && vs.getExpansion().hasContains()) {
|
||||
for (ValueSet.ValueSetExpansionContainsComponent vsecc : vs.getExpansion().getContains()) {
|
||||
codes.add(new Code().withCode(vsecc.getCode()).withSystem(vsecc.getSystem()));
|
||||
}
|
||||
}
|
||||
// If not, best-effort based on codes. Should probably make this configurable to match the behavior of the
|
||||
// underlying terminology service implementation
|
||||
else if (vs.hasCompose() && vs.getCompose().hasInclude()) {
|
||||
for (ValueSet.ConceptSetComponent include : vs.getCompose().getInclude()) {
|
||||
for (ValueSet.ConceptReferenceComponent concept : include.getConcept()) {
|
||||
if (concept.hasCode()) {
|
||||
codes.add(new Code().withCode(concept.getCode()).withSystem(include.getSystem()));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return codes;
|
||||
}
|
||||
|
|
|
@ -20,12 +20,11 @@ package ca.uhn.fhir.cql.r4.provider;
|
|||
* #L%
|
||||
*/
|
||||
|
||||
import ca.uhn.fhir.context.FhirContext;
|
||||
import ca.uhn.fhir.context.support.IValidationSupport;
|
||||
import ca.uhn.fhir.context.support.IValidationSupport.LookupCodeResult;
|
||||
import ca.uhn.fhir.context.support.ValidationSupportContext;
|
||||
import ca.uhn.fhir.context.support.ValueSetExpansionOptions;
|
||||
import ca.uhn.fhir.jpa.rp.r4.ValueSetResourceProvider;
|
||||
import ca.uhn.fhir.jpa.api.dao.IFhirResourceDao;
|
||||
import ca.uhn.fhir.jpa.searchparam.SearchParameterMap;
|
||||
import ca.uhn.fhir.jpa.term.api.ITermReadSvcR4;
|
||||
import ca.uhn.fhir.rest.api.server.IBundleProvider;
|
||||
|
@ -48,102 +47,98 @@ import java.util.List;
|
|||
@Component
|
||||
public class JpaTerminologyProvider implements TerminologyProvider {
|
||||
|
||||
private ITermReadSvcR4 terminologySvc;
|
||||
private ValueSetResourceProvider valueSetResourceProvider;
|
||||
private final IValidationSupport validationSupport;
|
||||
private ITermReadSvcR4 terminologySvc;
|
||||
private IFhirResourceDao<ValueSet> valueSetDao;
|
||||
private final IValidationSupport validationSupport;
|
||||
|
||||
@Autowired
|
||||
public JpaTerminologyProvider(ITermReadSvcR4 terminologySvc,
|
||||
ValueSetResourceProvider valueSetResourceProvider, IValidationSupport validationSupport) {
|
||||
this.terminologySvc = terminologySvc;
|
||||
this.valueSetResourceProvider = valueSetResourceProvider;
|
||||
this.validationSupport = validationSupport;
|
||||
}
|
||||
@Autowired
|
||||
public JpaTerminologyProvider(ITermReadSvcR4 terminologySvc, IFhirResourceDao<ValueSet> valueSetDao,
|
||||
IValidationSupport validationSupport) {
|
||||
this.terminologySvc = terminologySvc;
|
||||
this.valueSetDao = valueSetDao;
|
||||
this.validationSupport = validationSupport;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean in(Code code, ValueSetInfo valueSet) throws ResourceNotFoundException {
|
||||
for (Code c : expand(valueSet)) {
|
||||
if (c == null)
|
||||
continue;
|
||||
if (c.getCode().equals(code.getCode()) && c.getSystem().equals(code.getSystem())) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
@Override
|
||||
public boolean in(Code code, ValueSetInfo valueSet) throws ResourceNotFoundException {
|
||||
for (Code c : expand(valueSet)) {
|
||||
if (c == null)
|
||||
continue;
|
||||
if (c.getCode().equals(code.getCode()) && c.getSystem().equals(code.getSystem())) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Iterable<Code> expand(ValueSetInfo valueSet) throws ResourceNotFoundException {
|
||||
List<Code> codes = new ArrayList<>();
|
||||
boolean needsExpand = false;
|
||||
ValueSet vs;
|
||||
if (valueSet.getId().startsWith("http://") || valueSet.getId().startsWith("https://")) {
|
||||
if (valueSet.getVersion() != null
|
||||
|| (valueSet.getCodeSystems() != null && valueSet.getCodeSystems().size() > 0)) {
|
||||
if (!(valueSet.getCodeSystems().size() == 1 && valueSet.getCodeSystems().get(0).getVersion() == null)) {
|
||||
throw new UnsupportedOperationException(String.format(
|
||||
"Could not expand value set %s; version and code system bindings are not supported at this time.",
|
||||
valueSet.getId()));
|
||||
}
|
||||
}
|
||||
IBundleProvider bundleProvider = valueSetResourceProvider.getDao()
|
||||
.search(new SearchParameterMap().add(ValueSet.SP_URL, new UriParam(valueSet.getId())));
|
||||
List<IBaseResource> valueSets = bundleProvider.getResources(0, bundleProvider.size());
|
||||
if (valueSets.isEmpty()) {
|
||||
throw new IllegalArgumentException(String.format("Could not resolve value set %s.", valueSet.getId()));
|
||||
} else if (valueSets.size() == 1) {
|
||||
vs = (ValueSet) valueSets.get(0);
|
||||
} else {
|
||||
throw new IllegalArgumentException("Found more than 1 ValueSet with url: " + valueSet.getId());
|
||||
}
|
||||
} else {
|
||||
vs = valueSetResourceProvider.getDao().read(new IdType(valueSet.getId()));
|
||||
}
|
||||
if (vs != null) {
|
||||
if (vs.hasCompose()) {
|
||||
if (vs.getCompose().hasInclude()) {
|
||||
for (ValueSet.ConceptSetComponent include : vs.getCompose().getInclude()) {
|
||||
if (include.hasValueSet() || include.hasFilter()) {
|
||||
needsExpand = true;
|
||||
break;
|
||||
}
|
||||
for (ValueSet.ConceptReferenceComponent concept : include.getConcept()) {
|
||||
if (concept.hasCode()) {
|
||||
codes.add(new Code().withCode(concept.getCode()).withSystem(include.getSystem()));
|
||||
}
|
||||
}
|
||||
}
|
||||
if (!needsExpand) {
|
||||
return codes;
|
||||
}
|
||||
}
|
||||
}
|
||||
@Override
|
||||
public Iterable<Code> expand(ValueSetInfo valueSet) throws ResourceNotFoundException {
|
||||
// This could possibly be refactored into a single call to the underlying HAPI Terminology service. Need to think through that..,
|
||||
ValueSet vs;
|
||||
if (valueSet.getId().startsWith("http://") || valueSet.getId().startsWith("https://")) {
|
||||
if (valueSet.getVersion() != null
|
||||
|| (valueSet.getCodeSystems() != null && valueSet.getCodeSystems().size() > 0)) {
|
||||
if (!(valueSet.getCodeSystems().size() == 1 && valueSet.getCodeSystems().get(0).getVersion() == null)) {
|
||||
throw new UnsupportedOperationException(String.format(
|
||||
"Could not expand value set %s; version and code system bindings are not supported at this time.",
|
||||
valueSet.getId()));
|
||||
}
|
||||
}
|
||||
|
||||
if (vs.hasExpansion() && vs.getExpansion().hasContains()) {
|
||||
for (ValueSetExpansionContainsComponent vsecc : vs.getExpansion().getContains()) {
|
||||
codes.add(new Code().withCode(vsecc.getCode()).withSystem(vsecc.getSystem()));
|
||||
}
|
||||
IBundleProvider bundleProvider = this.valueSetDao
|
||||
.search(new SearchParameterMap().add(ValueSet.SP_URL, new UriParam(valueSet.getId())));
|
||||
List<IBaseResource> valueSets = bundleProvider.getResources(0, bundleProvider.size());
|
||||
if (valueSets.isEmpty()) {
|
||||
throw new IllegalArgumentException(String.format("Could not resolve value set %s.", valueSet.getId()));
|
||||
} else if (valueSets.size() == 1) {
|
||||
vs = (ValueSet) valueSets.get(0);
|
||||
} else {
|
||||
throw new IllegalArgumentException("Found more than 1 ValueSet with url: " + valueSet.getId());
|
||||
}
|
||||
} else {
|
||||
vs = this.valueSetDao.read(new IdType(valueSet.getId()));
|
||||
if (vs == null) {
|
||||
throw new IllegalArgumentException(String.format("Could not resolve value set %s.", valueSet.getId()));
|
||||
}
|
||||
}
|
||||
|
||||
return codes;
|
||||
}
|
||||
// Attempt to expand the ValueSet if it's not already expanded.
|
||||
if (!(vs.hasExpansion() && vs.getExpansion().hasContains())) {
|
||||
vs = (ValueSet)this.terminologySvc.expandValueSet(
|
||||
new ValueSetExpansionOptions().setCount(Integer.MAX_VALUE).setFailOnMissingCodeSystem(false), vs);
|
||||
}
|
||||
|
||||
}
|
||||
List<Code> codes = new ArrayList<>();
|
||||
|
||||
ValueSet expansion = terminologySvc
|
||||
.expandValueSet(new ValueSetExpansionOptions().setCount(Integer.MAX_VALUE), valueSet.getId(), null);
|
||||
expansion.getExpansion().getContains()
|
||||
.forEach(concept -> codes.add(new Code().withCode(concept.getCode()).withSystem(concept.getSystem())));
|
||||
// If expansion was successful, use the codes.
|
||||
if (vs.hasExpansion() && vs.getExpansion().hasContains()) {
|
||||
for (ValueSetExpansionContainsComponent vsecc : vs.getExpansion().getContains()) {
|
||||
codes.add(new Code().withCode(vsecc.getCode()).withSystem(vsecc.getSystem()));
|
||||
}
|
||||
}
|
||||
// If not, best-effort based on codes. Should probably make this configurable to match the behavior of the
|
||||
// underlying terminology service implementation
|
||||
else if (vs.hasCompose() && vs.getCompose().hasInclude()) {
|
||||
for (ValueSet.ConceptSetComponent include : vs.getCompose().getInclude()) {
|
||||
for (ValueSet.ConceptReferenceComponent concept : include.getConcept()) {
|
||||
if (concept.hasCode()) {
|
||||
codes.add(new Code().withCode(concept.getCode()).withSystem(include.getSystem()));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return codes;
|
||||
}
|
||||
return codes;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Code lookup(Code code, CodeSystemInfo codeSystem) throws ResourceNotFoundException {
|
||||
LookupCodeResult cs = terminologySvc.lookupCode(new ValidationSupportContext(validationSupport), codeSystem.getId(), code.getCode());
|
||||
@Override
|
||||
public Code lookup(Code code, CodeSystemInfo codeSystem) throws ResourceNotFoundException {
|
||||
LookupCodeResult cs = terminologySvc.lookupCode(new ValidationSupportContext(validationSupport),
|
||||
codeSystem.getId(), code.getCode());
|
||||
|
||||
code.setDisplay(cs.getCodeDisplay());
|
||||
code.setSystem(codeSystem.getId());
|
||||
code.setDisplay(cs.getCodeDisplay());
|
||||
code.setSystem(codeSystem.getId());
|
||||
|
||||
return code;
|
||||
}
|
||||
return code;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -4,6 +4,10 @@ import ca.uhn.fhir.jpa.subscription.channel.config.SubscriptionChannelConfig;
|
|||
import ca.uhn.fhir.jpa.subscription.submit.config.SubscriptionSubmitterConfig;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
import org.springframework.context.annotation.Import;
|
||||
import org.springframework.context.annotation.Bean;
|
||||
import org.springframework.context.annotation.Primary;
|
||||
|
||||
|
||||
|
||||
@Configuration
|
||||
@Import({SubscriptionSubmitterConfig.class, SubscriptionChannelConfig.class})
|
||||
|
|
|
@ -0,0 +1,51 @@
|
|||
package ca.uhn.fhir.cql.dstu3.provider;
|
||||
|
||||
import static org.hamcrest.MatcherAssert.assertThat;
|
||||
import static org.hamcrest.Matchers.hasSize;
|
||||
import static org.junit.jupiter.api.Assertions.assertNotNull;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
import org.junit.jupiter.api.BeforeEach;
|
||||
import org.junit.jupiter.api.Test;
|
||||
import org.opencds.cqf.cql.engine.runtime.Code;
|
||||
import org.opencds.cqf.cql.engine.terminology.TerminologyProvider;
|
||||
import org.opencds.cqf.cql.engine.terminology.ValueSetInfo;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
|
||||
import ca.uhn.fhir.cql.BaseCqlDstu3Test;
|
||||
import ca.uhn.fhir.jpa.api.config.DaoConfig;
|
||||
|
||||
public class JpaTerminologyProviderTest extends BaseCqlDstu3Test {
|
||||
private static final Logger ourLog = LoggerFactory.getLogger(JpaTerminologyProviderTest.class);
|
||||
|
||||
@Autowired
|
||||
protected TerminologyProvider jpaTerminologyProvider;
|
||||
|
||||
@Autowired
|
||||
protected DaoConfig daoConfig;
|
||||
|
||||
@BeforeEach
|
||||
public void before() throws IOException {
|
||||
// Load executable (i.e. "pre-expanded") value set
|
||||
loadResource("dstu3/provider/test-executable-value-set.json");
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testTerminologyProviderExpand() {
|
||||
ValueSetInfo valueSetInfo = new ValueSetInfo().withId("http://test.com/fhir/ValueSet/test-executable-value-set");
|
||||
Iterable<Code> codeIterable = this.jpaTerminologyProvider.expand(valueSetInfo);
|
||||
|
||||
assertNotNull(codeIterable);
|
||||
|
||||
List<Code> codes = new ArrayList<>();
|
||||
|
||||
codeIterable.forEach(codes::add);
|
||||
|
||||
assertThat(codes, hasSize(2));
|
||||
}
|
||||
}
|
|
@ -0,0 +1,54 @@
|
|||
package ca.uhn.fhir.cql.r4;
|
||||
|
||||
import static org.hamcrest.MatcherAssert.assertThat;
|
||||
import static org.hamcrest.Matchers.hasSize;
|
||||
import static org.junit.jupiter.api.Assertions.assertEquals;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.math.BigDecimal;
|
||||
|
||||
import org.hl7.fhir.r4.model.IdType;
|
||||
import org.hl7.fhir.r4.model.MeasureReport;
|
||||
import org.hl7.fhir.r4.model.Quantity;
|
||||
import org.hl7.fhir.r4.model.MeasureReport.MeasureReportGroupPopulationComponent;
|
||||
import org.junit.jupiter.api.BeforeEach;
|
||||
import org.junit.jupiter.api.Test;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
|
||||
import ca.uhn.fhir.cql.BaseCqlR4Test;
|
||||
import ca.uhn.fhir.cql.common.provider.CqlProviderTestBase;
|
||||
import ca.uhn.fhir.cql.r4.provider.MeasureOperationsProvider;
|
||||
|
||||
public class CqlMeasureEvaluationR4Test extends BaseCqlR4Test implements CqlProviderTestBase {
|
||||
|
||||
private static final IdType measureId = new IdType("Measure", "measure-EXM130-7.3.000");
|
||||
private static final String periodStart = "2019-01-01";
|
||||
private static final String periodEnd = "2019-12-31";
|
||||
|
||||
@Autowired
|
||||
MeasureOperationsProvider myMeasureOperationsProvider;
|
||||
|
||||
public void loadBundles() throws IOException {
|
||||
loadBundle("r4/connectathon/EXM130-7.3.000-bundle.json");
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testExm130PatientNumerator() throws IOException {
|
||||
loadBundles();
|
||||
MeasureReport report = myMeasureOperationsProvider.evaluateMeasure(measureId, periodStart, periodEnd, null, "patient",
|
||||
"numer-EXM130", null, null, null, null, null, null);
|
||||
// Assert it worked
|
||||
assertThat(report.getGroup(), hasSize(1));
|
||||
assertEquals(new BigDecimal("1.0"), report.getGroupFirstRep().getMeasureScore().getValue());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testExm130PatientDenominator() throws IOException {
|
||||
loadBundles();
|
||||
MeasureReport report = myMeasureOperationsProvider.evaluateMeasure(measureId, periodStart, periodEnd, null, "patient",
|
||||
"denom-EXM130", null, null, null, null, null, null);
|
||||
// Assert it worked
|
||||
assertThat(report.getGroup(), hasSize(1));
|
||||
assertEquals(new BigDecimal("0.0"), report.getGroupFirstRep().getMeasureScore().getValue());
|
||||
}
|
||||
}
|
|
@ -0,0 +1,51 @@
|
|||
package ca.uhn.fhir.cql.r4.provider;
|
||||
|
||||
import static org.hamcrest.MatcherAssert.assertThat;
|
||||
import static org.hamcrest.Matchers.hasSize;
|
||||
import static org.junit.jupiter.api.Assertions.assertNotNull;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
import org.junit.jupiter.api.BeforeEach;
|
||||
import org.junit.jupiter.api.Test;
|
||||
import org.opencds.cqf.cql.engine.runtime.Code;
|
||||
import org.opencds.cqf.cql.engine.terminology.TerminologyProvider;
|
||||
import org.opencds.cqf.cql.engine.terminology.ValueSetInfo;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
|
||||
import ca.uhn.fhir.cql.BaseCqlR4Test;
|
||||
import ca.uhn.fhir.jpa.api.config.DaoConfig;
|
||||
|
||||
public class JpaTerminologyProviderTest extends BaseCqlR4Test {
|
||||
private static final Logger ourLog = LoggerFactory.getLogger(JpaTerminologyProviderTest.class);
|
||||
|
||||
@Autowired
|
||||
protected TerminologyProvider jpaTerminologyProvider;
|
||||
|
||||
@Autowired
|
||||
protected DaoConfig daoConfig;
|
||||
|
||||
@BeforeEach
|
||||
public void before() throws IOException {
|
||||
// Load executable (i.e. "pre-expanded") value set
|
||||
loadResource("r4/provider/test-executable-value-set.json");
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testTerminologyProviderExpand() {
|
||||
ValueSetInfo valueSetInfo = new ValueSetInfo().withId("http://test.com/fhir/ValueSet/test-executable-value-set");
|
||||
Iterable<Code> codeIterable = this.jpaTerminologyProvider.expand(valueSetInfo);
|
||||
|
||||
assertNotNull(codeIterable);
|
||||
|
||||
List<Code> codes = new ArrayList<>();
|
||||
|
||||
codeIterable.forEach(codes::add);
|
||||
|
||||
assertThat(codes, hasSize(2));
|
||||
}
|
||||
}
|
|
@ -0,0 +1,39 @@
|
|||
{
|
||||
"resourceType": "ValueSet",
|
||||
"id": "test-executable-value-set",
|
||||
"meta" : {
|
||||
"profile" : [
|
||||
"http://hl7.org/fhir/uv/cpg/StructureDefinition/cpg-executablevalueset"
|
||||
]
|
||||
},
|
||||
"url": "http://test.com/fhir/ValueSet/test-executable-value-set",
|
||||
"extension" : [
|
||||
{
|
||||
"url" : "http://hl7.org/fhir/uv/cpg/StructureDefinition/cpg-knowledgeCapability",
|
||||
"valueCode" : "executable"
|
||||
},
|
||||
{
|
||||
"url" : "http://hl7.org/fhir/uv/cpg/StructureDefinition/cpg-knowledgeRepresentationLevel",
|
||||
"valueCode" : "executable"
|
||||
},
|
||||
{
|
||||
"url" : "http://hl7.org/fhir/uv/cpg/StructureDefinition/cpg-usageWarning",
|
||||
"valueString" : "This value set contains a point-in-time expansion enumerating the codes that meet the value set intent. As new versions of the code systems used by the value set are released, the contents of this expansion will need to be updated to incorporate newly defined codes that meet the value set intent. Before, and periodically during production use, the value set expansion contents SHOULD be updated. The value set expansion specifies the timestamp when the expansion was produced, SHOULD contain the parameters used for the expansion, and SHALL contain the codes that are obtained by evaluating the value set definition. If this is ONLY an executable value set, a distributable definition of the value set must be obtained to compute the updated expansion."
|
||||
}
|
||||
],
|
||||
"expansion": {
|
||||
"timestamp" : "2020-03-26T17:39:09-06:00",
|
||||
"contains" : [
|
||||
{
|
||||
"system" : "http://test.com/codesystem/test",
|
||||
"code" : "1234",
|
||||
"display" : "1234"
|
||||
},
|
||||
{
|
||||
"system" : "http://test.com/codesystem/test",
|
||||
"code" : "ABCD",
|
||||
"display" : "ABCD"
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
File diff suppressed because one or more lines are too long
|
@ -0,0 +1,39 @@
|
|||
{
|
||||
"resourceType": "ValueSet",
|
||||
"id": "test-executable-value-set",
|
||||
"meta" : {
|
||||
"profile" : [
|
||||
"http://hl7.org/fhir/uv/cpg/StructureDefinition/cpg-executablevalueset"
|
||||
]
|
||||
},
|
||||
"url": "http://test.com/fhir/ValueSet/test-executable-value-set",
|
||||
"extension" : [
|
||||
{
|
||||
"url" : "http://hl7.org/fhir/uv/cpg/StructureDefinition/cpg-knowledgeCapability",
|
||||
"valueCode" : "executable"
|
||||
},
|
||||
{
|
||||
"url" : "http://hl7.org/fhir/uv/cpg/StructureDefinition/cpg-knowledgeRepresentationLevel",
|
||||
"valueCode" : "executable"
|
||||
},
|
||||
{
|
||||
"url" : "http://hl7.org/fhir/uv/cpg/StructureDefinition/cpg-usageWarning",
|
||||
"valueString" : "This value set contains a point-in-time expansion enumerating the codes that meet the value set intent. As new versions of the code systems used by the value set are released, the contents of this expansion will need to be updated to incorporate newly defined codes that meet the value set intent. Before, and periodically during production use, the value set expansion contents SHOULD be updated. The value set expansion specifies the timestamp when the expansion was produced, SHOULD contain the parameters used for the expansion, and SHALL contain the codes that are obtained by evaluating the value set definition. If this is ONLY an executable value set, a distributable definition of the value set must be obtained to compute the updated expansion."
|
||||
}
|
||||
],
|
||||
"expansion": {
|
||||
"timestamp" : "2020-03-26T17:39:09-06:00",
|
||||
"contains" : [
|
||||
{
|
||||
"system" : "http://test.com/codesystem/test",
|
||||
"code" : "1234",
|
||||
"display" : "1234"
|
||||
},
|
||||
{
|
||||
"system" : "http://test.com/codesystem/test",
|
||||
"code" : "ABCD",
|
||||
"display" : "ABCD"
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
|
@ -1,7 +1,9 @@
|
|||
package ca.uhn.fhir.parser;
|
||||
|
||||
import ca.uhn.fhir.context.ConfigurationException;
|
||||
import ca.uhn.fhir.context.FhirContext;
|
||||
import ca.uhn.fhir.model.api.annotation.Child;
|
||||
import ca.uhn.fhir.model.api.annotation.DatatypeDef;
|
||||
import ca.uhn.fhir.model.api.annotation.Description;
|
||||
import ca.uhn.fhir.model.api.annotation.ResourceDef;
|
||||
import ca.uhn.fhir.rest.api.Constants;
|
||||
|
@ -20,6 +22,7 @@ import org.hl7.fhir.r4.model.Composition;
|
|||
import org.hl7.fhir.r4.model.DateTimeType;
|
||||
import org.hl7.fhir.r4.model.Device;
|
||||
import org.hl7.fhir.r4.model.DocumentReference;
|
||||
import org.hl7.fhir.r4.model.Dosage;
|
||||
import org.hl7.fhir.r4.model.Encounter;
|
||||
import org.hl7.fhir.r4.model.Extension;
|
||||
import org.hl7.fhir.r4.model.Medication;
|
||||
|
@ -30,10 +33,12 @@ import org.hl7.fhir.r4.model.Narrative;
|
|||
import org.hl7.fhir.r4.model.Observation;
|
||||
import org.hl7.fhir.r4.model.Patient;
|
||||
import org.hl7.fhir.r4.model.Practitioner;
|
||||
import org.hl7.fhir.r4.model.PrimitiveType;
|
||||
import org.hl7.fhir.r4.model.Quantity;
|
||||
import org.hl7.fhir.r4.model.QuestionnaireResponse;
|
||||
import org.hl7.fhir.r4.model.Reference;
|
||||
import org.hl7.fhir.r4.model.StringType;
|
||||
import org.hl7.fhir.r4.model.Type;
|
||||
import org.hl7.fhir.r4.model.UuidType;
|
||||
import org.hl7.fhir.utilities.xhtml.XhtmlNode;
|
||||
import org.junit.jupiter.api.AfterAll;
|
||||
|
@ -80,6 +85,20 @@ public class JsonParserR4Test extends BaseTest {
|
|||
ourLog.info(narrative);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testEncodeExtensionWithUnknownType() throws IOException {
|
||||
|
||||
Patient p = new Patient();
|
||||
p.addExtension("http://foo", new MyUnknownPrimitiveType());
|
||||
|
||||
try {
|
||||
ourCtx.newJsonParser().encodeResourceToString(p);
|
||||
fail();
|
||||
} catch (ConfigurationException e) {
|
||||
assertEquals("Unable to encode extension, unrecognized child element type: ca.uhn.fhir.parser.JsonParserR4Test.MyUnknownPrimitiveType", e.getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testNamespacePrefixTrimmedFromNarrative() {
|
||||
String input = "<Patient xmlns=\"http://hl7.org/fhir\" xmlns:xhtml=\"http://www.w3.org/1999/xhtml\">" +
|
||||
|
@ -910,6 +929,42 @@ public class JsonParserR4Test extends BaseTest {
|
|||
}
|
||||
|
||||
|
||||
@DatatypeDef(
|
||||
name = "UnknownPrimitiveType"
|
||||
)
|
||||
private static class MyUnknownPrimitiveType extends PrimitiveType<Object> {
|
||||
@Override
|
||||
public Object getValue() {
|
||||
return "AAA";
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getValueAsString() {
|
||||
return "AAA";
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isEmpty() {
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Type copy() {
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected String encode(Object theO) {
|
||||
return "AAA";
|
||||
}
|
||||
|
||||
@Override
|
||||
protected Object parse(String theS) {
|
||||
return new Object();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@AfterAll
|
||||
public static void afterClassClearContext() {
|
||||
TestUtil.clearAllStaticFieldsForUnitTest();
|
||||
|
|
|
@ -65,10 +65,23 @@ public class BundleUtilTest {
|
|||
}
|
||||
|
||||
@Test
|
||||
public void testProcessEntries() {
|
||||
public void testProcessEntriesSetRequestUrl() {
|
||||
Bundle bundle = new Bundle();
|
||||
bundle.setType(Bundle.BundleType.TRANSACTION);
|
||||
bundle.addEntry().getRequest().setMethod(Bundle.HTTPVerb.POST).setUrl("Patient");
|
||||
|
||||
Consumer<ModifiableBundleEntry> consumer = e -> e.setFullUrl("http://hello/Patient/123");
|
||||
BundleUtil.processEntries(ourCtx, bundle, consumer);
|
||||
|
||||
assertEquals("http://hello/Patient/123", bundle.getEntryFirstRep().getFullUrl());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testProcessEntriesSetFullUrl() {
|
||||
Bundle bundle = new Bundle();
|
||||
bundle.setType(Bundle.BundleType.TRANSACTION);
|
||||
bundle.addEntry().getRequest().setMethod(Bundle.HTTPVerb.GET).setUrl("Observation");
|
||||
|
||||
Consumer<ModifiableBundleEntry> consumer = e -> e.setRequestUrl(ourCtx, e.getRequestUrl() + "?foo=bar");
|
||||
BundleUtil.processEntries(ourCtx, bundle, consumer);
|
||||
assertEquals("Observation?foo=bar", bundle.getEntryFirstRep().getRequest().getUrl());
|
||||
|
|
9
pom.xml
9
pom.xml
|
@ -818,12 +818,9 @@
|
|||
|
||||
<elastic_apm_version>1.13.0</elastic_apm_version>
|
||||
<!-- CQL Support -->
|
||||
<!-- FIXME KBD: Change all of these -SNAPSHOT versions to release versions
|
||||
(e.g. 1.3.1-SNAPSHOT -> 1.3.1) before finalizing this work! -->
|
||||
<cqf-tooling.version>1.3.1-SNAPSHOT</cqf-tooling.version>
|
||||
<cql-engine.version>1.5.1-SNAPSHOT</cql-engine.version>
|
||||
<cql-evaluator.version>1.1.0-SNAPSHOT</cql-evaluator.version>
|
||||
<cqframework.version>1.5.2-SNAPSHOT</cqframework.version>
|
||||
<cql-engine.version>1.5.1</cql-engine.version>
|
||||
<cql-evaluator.version>1.1.0</cql-evaluator.version>
|
||||
<cqframework.version>1.5.1</cqframework.version>
|
||||
|
||||
<!-- Site properties -->
|
||||
<fontawesomeVersion>5.4.1</fontawesomeVersion>
|
||||
|
|
Loading…
Reference in New Issue