Skip to content
Merged
Show file tree
Hide file tree
Changes from 2 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,7 @@
* search, but found that the performance was reduced by ~33%. Please run the benchmarks to verify
* that changes to this class do not result in significant performance degradation.
*/
@SuppressWarnings("UnstableApiUsage")
public class RepositoryTerminologyProvider implements TerminologyProvider {

private static final Logger logger = LoggerFactory.getLogger(RepositoryTerminologyProvider.class);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,14 +9,15 @@

import ca.uhn.fhir.context.FhirContext;
import ca.uhn.fhir.repository.IRepository;
import java.util.Map;
import com.google.common.collect.Multimap;
import org.hl7.fhir.r4.model.Bundle;
import org.hl7.fhir.r4.model.ValueSet;
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;

@SuppressWarnings("UnstableApiUsage")
class RepositoryTerminologyProviderTest {

private static final String SYSTEM_FOR_CODES = "http://example.com/CodeSystem/Codes";
Expand Down Expand Up @@ -77,7 +78,7 @@ IRepository mockRepositoryWithValueSet(ValueSet valueSet) {
when(mockRepository.fhirContext()).thenReturn(FhirContext.forR4Cached());
Bundle bundle = new Bundle();
bundle.addEntry().setFullUrl(valueSet.getUrl()).setResource(valueSet);
when(mockRepository.search(any(), any(), any(Map.class), isNull())).thenReturn(bundle);
when(mockRepository.search(any(), any(), any(Multimap.class), isNull())).thenReturn(bundle);
return mockRepository;
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
import static org.opencds.cqf.fhir.utility.Resources.castOrThrow;

import ca.uhn.fhir.repository.IRepository;
import ca.uhn.fhir.util.bundle.BundleEntryParts;
import java.util.function.Function;
import org.hl7.fhir.exceptions.FHIRException;
import org.hl7.fhir.instance.model.api.IBaseBundle;
Expand All @@ -15,6 +16,7 @@
import org.opencds.cqf.fhir.utility.monad.Either3;
import org.opencds.cqf.fhir.utility.search.Searches;

@SuppressWarnings("UnstableApiUsage")
public class ResourceResolver {
final String invalidResourceType = "The resource passed in was not a valid instance of %s.class";
final String resourceType;
Expand Down Expand Up @@ -50,7 +52,7 @@ public ResourceResolver(String resourceType, IRepository repository) {

protected <C extends IPrimitiveType<String>> IBaseResource resolveByUrl(C url) {
var result = this.repository.search(bundleClazz, clazz, Searches.byCanonical(url.getValue()));
var iterator = new BundleMappingIterable<>(repository, result, p -> p.getResource()).iterator();
var iterator = new BundleMappingIterable<>(repository, result, BundleEntryParts::getResource).iterator();
return iterator.hasNext() ? iterator.next() : null;
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@
import ca.uhn.fhir.rest.param.ReferenceParam;
import ca.uhn.fhir.rest.server.exceptions.InvalidRequestException;
import ca.uhn.fhir.rest.server.exceptions.UnprocessableEntityException;
import com.google.common.collect.Multimap;
import java.util.Collections;
import java.util.Date;
import java.util.HashMap;
Expand Down Expand Up @@ -143,7 +144,7 @@
return sectionComponent;
}

protected Map<String, List<IQueryParameterType>> getSearchParams(
protected Multimap<String, List<IQueryParameterType>> getSearchParams(
ApplyRequest request, String type, String profile) {
var searchParams = Searches.byProfile(profile);
searchParams.put(
Expand Down Expand Up @@ -179,7 +180,7 @@
Map<String, List<IQueryParameterType>> searchParameters = new HashMap<>();
searchParameters.put("practitioner", Collections.singletonList(new ReferenceParam(practitionerId)));

Bundle bundle = repository.search(Bundle.class, PractitionerRole.class, searchParameters);

Check warning on line 183 in cqf-fhir-cr/src/main/java/org/opencds/cqf/fhir/cr/graphdefinition/apply/ApplyProcessor.java

View check run for this annotation

SonarQubeCloud / SonarCloud Code Analysis

Remove this use of "search"; it is deprecated.

See more on https://sonarcloud.io/project/issues?id=cqframework_clinical-reasoning&issues=AZz3N1NN49yrFVO9uJVA&open=AZz3N1NN49yrFVO9uJVA&pullRequest=969

return BundleHelper.getEntryResources(bundle);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,6 @@
import com.google.common.collect.Multimap;
import java.util.Arrays;
import java.util.List;
import java.util.Map;
import org.hl7.fhir.instance.model.api.IBaseExtension;
import org.hl7.fhir.r4.model.Bundle;
import org.hl7.fhir.r4.model.Bundle.BundleEntryComponent;
Expand Down Expand Up @@ -570,7 +569,7 @@ void testResolveInputParametersWithDataRequirements() {
var obsBundle = new Bundle().addEntry(new BundleEntryComponent().setResource(obs));
doReturn(fhirContextR4).when(repository).fhirContext();
doReturn(patient).when(repository).read(org.hl7.fhir.r4.model.Patient.class, patient.getIdElement());
doReturn(valueSetBundle).when(repository).search(eq(Bundle.class), eq(ValueSet.class), any(Map.class));
doReturn(valueSetBundle).when(repository).search(eq(Bundle.class), eq(ValueSet.class), any(Multimap.class));
doReturn(obsBundle)
.when(repository)
.search(eq(Bundle.class), eq(Observation.class), any(Multimap.class), any());
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@
import java.nio.file.Path;
import java.util.List;
import org.hl7.fhir.r4.model.Library;
import org.hl7.fhir.r4.model.StringType;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.extension.ExtendWith;
import org.mockito.Mock;
Expand Down Expand Up @@ -201,4 +202,31 @@ void testPrefetchData() {
.thenEvaluate()
.hasResults(6);
}

@Test
void testEvaluateMultipleLibraryVersions() {
var libraryUrl = "http://fhir.org/guides/cdc/opioid-cds/Library/HelloWorld";
var version1 = "1.0.0";
var version2 = "2.0.0";
var repository =
new IgRepository(fhirContextR4, Path.of(getResourcePath(this.getClass()) + "/" + CLASS_PATH + "/r4"));
var evaluationSettings = EvaluationSettings.getDefault();
given().repository(repository)
.evaluationSettings(evaluationSettings)
.when()
.libraryUrl(String.format("%s|%s", libraryUrl, version1))
.subjectId("Patient1")
.thenEvaluate()
.hasResults(8)
.resultHasValue(3, new StringType("Hello World!"));

given().repository(repository)
.evaluationSettings(evaluationSettings)
.when()
.libraryUrl(String.format("%s|%s", libraryUrl, version2))
.subjectId("Patient1")
.thenEvaluate()
.hasResults(8)
.resultHasValue(3, new StringType("Hello World! I am a new version!"));
}
}
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
package org.opencds.cqf.fhir.cr.library;

import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.junit.jupiter.api.Assertions.assertInstanceOf;
import static org.junit.jupiter.api.Assertions.assertTrue;
import static org.opencds.cqf.fhir.test.Resources.getResourcePath;
import static org.opencds.cqf.fhir.utility.BundleHelper.addEntry;
Expand Down Expand Up @@ -28,6 +29,7 @@
import org.hl7.fhir.instance.model.api.IBaseParameters;
import org.hl7.fhir.instance.model.api.IBaseResource;
import org.hl7.fhir.instance.model.api.IIdType;
import org.hl7.fhir.instance.model.api.IPrimitiveType;
import org.opencds.cqf.cql.engine.model.ModelResolver;
import org.opencds.cqf.fhir.cql.EvaluationSettings;
import org.opencds.cqf.fhir.cql.engine.retrieve.RetrieveSettings.SEARCH_FILTER_MODE;
Expand All @@ -38,6 +40,7 @@
import org.opencds.cqf.fhir.cr.helpers.DataRequirementsLibrary;
import org.opencds.cqf.fhir.cr.helpers.GeneratedPackage;
import org.opencds.cqf.fhir.utility.Ids;
import org.opencds.cqf.fhir.utility.adapter.IAdapterFactory;
import org.opencds.cqf.fhir.utility.model.FhirModelResolverCache;
import org.opencds.cqf.fhir.utility.monad.Eithers;
import org.opencds.cqf.fhir.utility.repository.InMemoryFhirRepository;
Expand Down Expand Up @@ -288,7 +291,8 @@ public static class Evaluation {
final IBaseParameters result;
final IParser jsonParser;
final ModelResolver modelResolver;
final List<IBaseResource> parameter;
final List<IBase> parameter;
final IAdapterFactory adapterFactory;

@SuppressWarnings("unchecked")
public Evaluation(IRepository repository, IBaseParameters result) {
Expand All @@ -297,7 +301,8 @@ public Evaluation(IRepository repository, IBaseParameters result) {
jsonParser = this.repository.fhirContext().newJsonParser().setPrettyPrint(true);
modelResolver = FhirModelResolverCache.resolverForVersion(
this.repository.fhirContext().getVersion().getVersion());
parameter = ((List<IBaseResource>) modelResolver.resolvePath(result, "parameter"));
adapterFactory = IAdapterFactory.forFhirContext(this.repository.fhirContext());
parameter = ((List<IBase>) modelResolver.resolvePath(result, "parameter"));
}

public Evaluation hasResults(Integer count) {
Expand All @@ -310,9 +315,16 @@ public Evaluation hasOperationOutcome() {
return this;
}

@SuppressWarnings("unchecked")
public Evaluation resultHasValue(Integer index, IBase value) {
var actual = parameter.get(index);
assertEquals(value, actual);
var actual = adapterFactory
.createParametersParameter(parameter.get(index))
.getValue();
if (value instanceof IPrimitiveType<?> primitiveValue) {
assertEquals(primitiveValue.getValueAsString(), ((IPrimitiveType<String>) actual).getValueAsString());
} else {
assertInstanceOf(value.getClass(), actual);
}
return this;
}
}
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
library HelloWorld version '2.0.0'

using FHIR version '4.0.1'

include FHIRHelpers version '4.0.1'


context Patient

define "Info":
'info'

define "Warning":
'warning'

define "Critical":
'critical'

define "Main Action Condition Expression Is True":
true

define "Get Title":
'Hello World! I am a new version!'

define "Get Description":
'The CDS Service is alive and communicating successfully!'

define "Get Indicator":
'info'
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@
],
"url": "http://fhir.org/guides/cdc/opioid-cds/Library/BadLibrary",
"version": "1.0.0",
"name": "HelloWorld",
"name": "NotACorrectLibraryName",
"relatedArtifact": [
{
"type": "depends-on",
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,94 @@
{
"resourceType": "Library",
"id": "HelloWorld2",
"extension": [
{
"url": "http://hl7.org/fhir/us/cqfmeasures/StructureDefinition/cqfm-softwaresystem",
"valueReference": {
"reference": "Device/cqf-tooling"
}
}
],
"url": "http://fhir.org/guides/cdc/opioid-cds/Library/HelloWorld",
"version": "2.0.0",
"name": "HelloWorld",
"relatedArtifact": [
{
"type": "depends-on",
"display": "FHIR model information",
"resource": "http://fhir.org/guides/cqf/common/Library/FHIR-ModelInfo|4.0.1"
}
],
"parameter": [
{
"name": "Patient",
"use": "out",
"min": 0,
"max": "1",
"type": "Patient"
},
{
"name": "Info",
"use": "out",
"min": 0,
"max": "1",
"type": "string"
},
{
"name": "Warning",
"use": "out",
"min": 0,
"max": "1",
"type": "string"
},
{
"name": "Critical",
"use": "out",
"min": 0,
"max": "1",
"type": "string"
},
{
"name": "Main Action Condition Expression Is True",
"use": "out",
"min": 0,
"max": "1",
"type": "boolean"
},
{
"name": "Get Title",
"use": "out",
"min": 0,
"max": "1",
"type": "string"
},
{
"name": "Get Description",
"use": "out",
"min": 0,
"max": "1",
"type": "string"
},
{
"name": "Get Indicator",
"use": "out",
"min": 0,
"max": "1",
"type": "string"
}
],
"dataRequirement": [
{
"type": "Patient",
"profile": [
"http://hl7.org/fhir/StructureDefinition/Patient"
]
}
],
"content": [
{
"contentType": "text/cql",
"url": "../cql/HelloWorld2.cql"
}
]
}
Original file line number Diff line number Diff line change
Expand Up @@ -56,7 +56,7 @@
"usage": "This is to be used in conjunction with a patient-facing FHIR application.",
"copyright": "© CDC 2016+.",
"library": [
"http://fhir.org/guides/cdc/opioid-cds/Library/HelloWorld"
"http://fhir.org/guides/cdc/opioid-cds/Library/HelloWorld|1.0.0"
],
"action": [
{
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@
import org.opencds.cqf.fhir.utility.adapter.IDependencyInfo;
import org.opencds.cqf.fhir.utility.search.Searches;

@SuppressWarnings("UnstableApiUsage")
public class SearchHelper {

private SearchHelper() {}
Expand Down Expand Up @@ -297,7 +298,9 @@ public static <CanonicalType extends IPrimitiveType<String>> IBaseBundle searchR
* @return
*/
public static IBaseBundle searchRepositoryByCanonicalWithPagingWithParams(
IRepository repository, String canonical, Map<String, List<IQueryParameterType>> additionalSearchParams) {
IRepository repository,
String canonical,
Multimap<String, List<IQueryParameterType>> additionalSearchParams) {
var resourceType = getResourceType(repository, canonical);
return searchRepositoryByCanonicalWithPagingWithParams(
repository, canonical, resourceType, additionalSearchParams);
Expand Down Expand Up @@ -335,16 +338,14 @@ IBaseBundle searchRepositoryByCanonicalWithPagingWithParams(
IRepository repository,
CanonicalType canonical,
Class<R> resourceType,
Map<String, List<IQueryParameterType>> additionalSearchParams) {
Multimap<String, List<IQueryParameterType>> additionalSearchParams) {
var url = Canonicals.getUrl(canonical);
var version = Canonicals.getVersion(canonical);
var searchParams = version == null ? Searches.byUrl(url) : Searches.byUrlAndVersion(url, version);
if (additionalSearchParams != null) {
searchParams.putAll(additionalSearchParams);
}
var searchResult = searchRepositoryWithPaging(repository, resourceType, searchParams, Collections.emptyMap());

return searchResult;
return searchRepositoryWithPaging(repository, resourceType, searchParams, Collections.emptyMap());
}

/**
Expand Down Expand Up @@ -375,16 +376,14 @@ public static <R extends IBaseResource> IBaseBundle searchRepositoryByCanonicalW
IRepository repository,
String canonical,
Class<R> resourceType,
Map<String, List<IQueryParameterType>> additionalSearchParams) {
Multimap<String, List<IQueryParameterType>> additionalSearchParams) {
var url = Canonicals.getUrl(canonical);
var version = Canonicals.getVersion(canonical);
var searchParams = version == null ? Searches.byUrl(url) : Searches.byUrlAndVersion(url, version);
if (additionalSearchParams != null) {
searchParams.putAll(additionalSearchParams);
}
var searchResult = searchRepositoryWithPaging(repository, resourceType, searchParams, Collections.emptyMap());

return searchResult;
return searchRepositoryWithPaging(repository, resourceType, searchParams, Collections.emptyMap());
}

/**
Expand Down
Loading
Loading