diff --git a/cqf-fhir-benchmark/src/test/java/org/opencds/cqf/fhir/benchmark/measure/r4/Measure.java b/cqf-fhir-benchmark/src/test/java/org/opencds/cqf/fhir/benchmark/measure/r4/Measure.java index a79d0446fa..e611583443 100644 --- a/cqf-fhir-benchmark/src/test/java/org/opencds/cqf/fhir/benchmark/measure/r4/Measure.java +++ b/cqf-fhir-benchmark/src/test/java/org/opencds/cqf/fhir/benchmark/measure/r4/Measure.java @@ -149,10 +149,6 @@ public When evaluate() { null, null, null, - null, - additionalData, - null, - null, null); return this; } diff --git a/cqf-fhir-cr-hapi/src/main/java/org/opencds/cqf/fhir/cr/hapi/config/dstu3/CrDstu3Config.java b/cqf-fhir-cr-hapi/src/main/java/org/opencds/cqf/fhir/cr/hapi/config/dstu3/CrDstu3Config.java index 2363be9dcd..b0f736837b 100644 --- a/cqf-fhir-cr-hapi/src/main/java/org/opencds/cqf/fhir/cr/hapi/config/dstu3/CrDstu3Config.java +++ b/cqf-fhir-cr-hapi/src/main/java/org/opencds/cqf/fhir/cr/hapi/config/dstu3/CrDstu3Config.java @@ -26,7 +26,8 @@ public class CrDstu3Config { @Bean IMeasureServiceFactory dstu3MeasureServiceFactory( IRepositoryFactory repositoryFactory, MeasureEvaluationOptions evaluationOptions) { - return rd -> new Dstu3MeasureService(repositoryFactory.create(rd), evaluationOptions); + return (requestDetails, environment) -> new Dstu3MeasureService( + environment.resolve(repositoryFactory.create(requestDetails)), evaluationOptions); } @Bean diff --git a/cqf-fhir-cr-hapi/src/main/java/org/opencds/cqf/fhir/cr/hapi/config/r4/CrR4Config.java b/cqf-fhir-cr-hapi/src/main/java/org/opencds/cqf/fhir/cr/hapi/config/r4/CrR4Config.java index 0695e47b6f..2cc201c943 100644 --- a/cqf-fhir-cr-hapi/src/main/java/org/opencds/cqf/fhir/cr/hapi/config/r4/CrR4Config.java +++ b/cqf-fhir-cr-hapi/src/main/java/org/opencds/cqf/fhir/cr/hapi/config/r4/CrR4Config.java @@ -75,8 +75,8 @@ R4MeasureEvaluatorSingleFactory r4MeasureServiceFactory( MeasureEvaluationOptions evaluationOptions, MeasurePeriodValidator measurePeriodValidator) { // We are effectively returning an R4MeasureEvaluatorSingle her - return requestDetails -> new R4MultiMeasureService( - repositoryFactory.create(requestDetails), + return (requestDetails, environment) -> new R4MultiMeasureService( + environment.resolve(repositoryFactory.create(requestDetails)), evaluationOptions, requestDetails.getFhirServerBase(), measurePeriodValidator); @@ -87,8 +87,11 @@ R4MeasureEvaluatorMultipleFactory r4MeasureEvaluatorMultipleFactory( IRepositoryFactory repositoryFactory, MeasureEvaluationOptions evaluationOptions, MeasurePeriodValidator measurePeriodValidator) { - return rd -> new R4MultiMeasureService( - repositoryFactory.create(rd), evaluationOptions, rd.getFhirServerBase(), measurePeriodValidator); + return (requestDetails, environment) -> new R4MultiMeasureService( + environment.resolve(repositoryFactory.create(requestDetails)), + evaluationOptions, + requestDetails.getFhirServerBase(), + measurePeriodValidator); } @Bean diff --git a/cqf-fhir-cr-hapi/src/main/java/org/opencds/cqf/fhir/cr/hapi/dstu3/IMeasureServiceFactory.java b/cqf-fhir-cr-hapi/src/main/java/org/opencds/cqf/fhir/cr/hapi/dstu3/IMeasureServiceFactory.java index 538a07ea2e..f754fe4160 100644 --- a/cqf-fhir-cr-hapi/src/main/java/org/opencds/cqf/fhir/cr/hapi/dstu3/IMeasureServiceFactory.java +++ b/cqf-fhir-cr-hapi/src/main/java/org/opencds/cqf/fhir/cr/hapi/dstu3/IMeasureServiceFactory.java @@ -1,9 +1,10 @@ package org.opencds.cqf.fhir.cr.hapi.dstu3; import ca.uhn.fhir.rest.api.server.RequestDetails; +import org.opencds.cqf.fhir.cr.measure.common.MeasureEnvironment; import org.opencds.cqf.fhir.cr.measure.dstu3.Dstu3MeasureService; @FunctionalInterface public interface IMeasureServiceFactory { - Dstu3MeasureService create(RequestDetails requestDetails); + Dstu3MeasureService create(RequestDetails requestDetails, MeasureEnvironment environment); } diff --git a/cqf-fhir-cr-hapi/src/main/java/org/opencds/cqf/fhir/cr/hapi/dstu3/measure/MeasureOperationsProvider.java b/cqf-fhir-cr-hapi/src/main/java/org/opencds/cqf/fhir/cr/hapi/dstu3/measure/MeasureOperationsProvider.java index a6db93e2fd..6fdc6c4aa2 100644 --- a/cqf-fhir-cr-hapi/src/main/java/org/opencds/cqf/fhir/cr/hapi/dstu3/measure/MeasureOperationsProvider.java +++ b/cqf-fhir-cr-hapi/src/main/java/org/opencds/cqf/fhir/cr/hapi/dstu3/measure/MeasureOperationsProvider.java @@ -18,6 +18,7 @@ import org.hl7.fhir.dstu3.model.Parameters.ParametersParameterComponent; import org.hl7.fhir.exceptions.FHIRException; import org.opencds.cqf.fhir.cr.hapi.dstu3.IMeasureServiceFactory; +import org.opencds.cqf.fhir.cr.measure.common.MeasureEnvironment; import org.springframework.stereotype.Component; @Component @@ -72,8 +73,9 @@ public MeasureReport evaluateMeasure( RequestDetails requestDetails) throws InternalErrorException, FHIRException { var terminologyEndpointParam = (Endpoint) getEndpoint(fhirVersion, terminologyEndpoint); + var environment = new MeasureEnvironment(null, terminologyEndpointParam, null, additionalData); return dstu3MeasureProcessorFactory - .create(requestDetails) + .create(requestDetails, environment) .evaluateMeasure( id, periodStart, @@ -83,8 +85,6 @@ public MeasureReport evaluateMeasure( practitioner, lastReceivedOn, productLine, - additionalData, - parameters, - terminologyEndpointParam); + parameters); } } diff --git a/cqf-fhir-cr-hapi/src/main/java/org/opencds/cqf/fhir/cr/hapi/r4/R4MeasureEvaluatorMultipleFactory.java b/cqf-fhir-cr-hapi/src/main/java/org/opencds/cqf/fhir/cr/hapi/r4/R4MeasureEvaluatorMultipleFactory.java index 5e4434dc6b..77f32e4cc9 100644 --- a/cqf-fhir-cr-hapi/src/main/java/org/opencds/cqf/fhir/cr/hapi/r4/R4MeasureEvaluatorMultipleFactory.java +++ b/cqf-fhir-cr-hapi/src/main/java/org/opencds/cqf/fhir/cr/hapi/r4/R4MeasureEvaluatorMultipleFactory.java @@ -1,9 +1,10 @@ package org.opencds.cqf.fhir.cr.hapi.r4; import ca.uhn.fhir.rest.api.server.RequestDetails; +import org.opencds.cqf.fhir.cr.measure.common.MeasureEnvironment; import org.opencds.cqf.fhir.cr.measure.r4.R4MeasureEvaluatorMultiple; @FunctionalInterface public interface R4MeasureEvaluatorMultipleFactory { - R4MeasureEvaluatorMultiple create(RequestDetails requestDetails); + R4MeasureEvaluatorMultiple create(RequestDetails requestDetails, MeasureEnvironment environment); } diff --git a/cqf-fhir-cr-hapi/src/main/java/org/opencds/cqf/fhir/cr/hapi/r4/R4MeasureEvaluatorSingleFactory.java b/cqf-fhir-cr-hapi/src/main/java/org/opencds/cqf/fhir/cr/hapi/r4/R4MeasureEvaluatorSingleFactory.java index a2279dc7dd..d213110b58 100644 --- a/cqf-fhir-cr-hapi/src/main/java/org/opencds/cqf/fhir/cr/hapi/r4/R4MeasureEvaluatorSingleFactory.java +++ b/cqf-fhir-cr-hapi/src/main/java/org/opencds/cqf/fhir/cr/hapi/r4/R4MeasureEvaluatorSingleFactory.java @@ -1,9 +1,10 @@ package org.opencds.cqf.fhir.cr.hapi.r4; import ca.uhn.fhir.rest.api.server.RequestDetails; +import org.opencds.cqf.fhir.cr.measure.common.MeasureEnvironment; import org.opencds.cqf.fhir.cr.measure.r4.R4MeasureEvaluatorSingle; @FunctionalInterface public interface R4MeasureEvaluatorSingleFactory { - R4MeasureEvaluatorSingle create(RequestDetails requestDetails); + R4MeasureEvaluatorSingle create(RequestDetails requestDetails, MeasureEnvironment environment); } diff --git a/cqf-fhir-cr-hapi/src/main/java/org/opencds/cqf/fhir/cr/hapi/r4/measure/MeasureOperationsProvider.java b/cqf-fhir-cr-hapi/src/main/java/org/opencds/cqf/fhir/cr/hapi/r4/measure/MeasureOperationsProvider.java index 342d696ef9..3e1012f889 100644 --- a/cqf-fhir-cr-hapi/src/main/java/org/opencds/cqf/fhir/cr/hapi/r4/measure/MeasureOperationsProvider.java +++ b/cqf-fhir-cr-hapi/src/main/java/org/opencds/cqf/fhir/cr/hapi/r4/measure/MeasureOperationsProvider.java @@ -20,6 +20,7 @@ import org.opencds.cqf.fhir.cr.hapi.common.StringTimePeriodHandler; import org.opencds.cqf.fhir.cr.hapi.r4.R4MeasureEvaluatorMultipleFactory; import org.opencds.cqf.fhir.cr.hapi.r4.R4MeasureEvaluatorSingleFactory; +import org.opencds.cqf.fhir.cr.measure.common.MeasureEnvironment; import org.opencds.cqf.fhir.cr.measure.common.MeasureReference; @SuppressWarnings("java:S107") @@ -87,8 +88,10 @@ public MeasureReport evaluateMeasure( var contentEndpointParam = (Endpoint) getEndpoint(fhirVersion, contentEndpoint); var terminologyEndpointParam = (Endpoint) getEndpoint(fhirVersion, terminologyEndpoint); var dataEndpointParam = (Endpoint) getEndpoint(fhirVersion, dataEndpoint); + var environment = new MeasureEnvironment( + contentEndpointParam, terminologyEndpointParam, dataEndpointParam, additionalData); return r4MeasureServiceFactory - .create(requestDetails) + .create(requestDetails, environment) .evaluate( new MeasureReference.ById(id), stringTimePeriodHandler.getStartZonedDateTime(periodStart, requestDetails), @@ -96,10 +99,6 @@ public MeasureReport evaluateMeasure( reportType, subject, lastReceivedOn, - contentEndpointParam, - terminologyEndpointParam, - dataEndpointParam, - additionalData, parameters, productLine, practitioner); @@ -157,18 +156,16 @@ public Parameters evaluate( var terminologyEndpointParam = (Endpoint) getEndpoint(fhirVersion, terminologyEndpoint); var dataEndpointParam = (Endpoint) getEndpoint(fhirVersion, dataEndpoint); var measureRefs = MeasureReference.fromOperationParams(measureId, measureIdentifier, measureUrl); + var environment = new MeasureEnvironment( + contentEndpointParam, terminologyEndpointParam, dataEndpointParam, additionalData); return r4MultiMeasureServiceFactory - .create(requestDetails) + .create(requestDetails, environment) .evaluate( measureRefs, stringTimePeriodHandler.getStartZonedDateTime(periodStart, requestDetails), stringTimePeriodHandler.getEndZonedDateTime(periodEnd, requestDetails), reportType, subject, - contentEndpointParam, - terminologyEndpointParam, - dataEndpointParam, - additionalData, parameters, productLine, reporter); diff --git a/cqf-fhir-cr/src/main/java/org/opencds/cqf/fhir/cr/measure/common/MeasureEnvironment.java b/cqf-fhir-cr/src/main/java/org/opencds/cqf/fhir/cr/measure/common/MeasureEnvironment.java new file mode 100644 index 0000000000..88e0a8fff7 --- /dev/null +++ b/cqf-fhir-cr/src/main/java/org/opencds/cqf/fhir/cr/measure/common/MeasureEnvironment.java @@ -0,0 +1,58 @@ +package org.opencds.cqf.fhir.cr.measure.common; + +import ca.uhn.fhir.repository.IRepository; +import jakarta.annotation.Nullable; +import org.hl7.fhir.instance.model.api.IBaseBundle; +import org.hl7.fhir.instance.model.api.IBaseResource; +import org.opencds.cqf.fhir.utility.repository.FederatedRepository; +import org.opencds.cqf.fhir.utility.repository.InMemoryFhirRepository; +import org.opencds.cqf.fhir.utility.repository.Repositories; + +/** + * Version-agnostic environment configuration for measure evaluation. + * + *
Separates the infrastructure inputs (where data, content, and terminology come from) + * from the operation parameters (what to evaluate). Per the pipeline architecture, + * environment resolution happens before domain logic: the service layer composes a + * {@code ProxyRepository} from these endpoints and passes it to the evaluator. + * + *
Endpoint resources are typed as {@link IBaseResource} so both R4 and DSTU3 + * {@code Endpoint} instances can be carried without version coupling. + * {@code Repositories.proxy()} already accepts {@code IBaseResource} endpoints directly. + * + * @param contentEndpoint endpoint for library/content resolution (nullable) + * @param terminologyEndpoint endpoint for terminology resolution (nullable) + * @param dataEndpoint endpoint for clinical data retrieval (nullable) + * @param additionalData supplemental data bundle for repository federation and CQL engine + * configuration (nullable) + */ +public record MeasureEnvironment( + @Nullable IBaseResource contentEndpoint, + @Nullable IBaseResource terminologyEndpoint, + @Nullable IBaseResource dataEndpoint, + @Nullable IBaseBundle additionalData) { + + /** Empty environment — no endpoints, no additional data. */ + public static final MeasureEnvironment EMPTY = new MeasureEnvironment(null, null, null, null); + + /** + * Resolves this environment against a base repository. + * + *
If any endpoint is present, wraps {@code base} in a {@code ProxyRepository}; null
+ * endpoints fall back to {@code base}. If {@code additionalData} is present, federates
+ * the result with an in-memory repository seeded from that bundle.
+ *
+ * @param base the base repository to build on top of
+ * @return the resolved repository, possibly wrapped
+ */
+ public IRepository resolve(IRepository base) {
+ IRepository repo = base;
+ if (dataEndpoint() != null || contentEndpoint() != null || terminologyEndpoint() != null) {
+ repo = Repositories.proxy(repo, true, dataEndpoint(), contentEndpoint(), terminologyEndpoint());
+ }
+ if (additionalData() != null) {
+ repo = new FederatedRepository(repo, new InMemoryFhirRepository(repo.fhirContext(), additionalData()));
+ }
+ return repo;
+ }
+}
diff --git a/cqf-fhir-cr/src/main/java/org/opencds/cqf/fhir/cr/measure/dstu3/Dstu3MeasureEvaluatorSingle.java b/cqf-fhir-cr/src/main/java/org/opencds/cqf/fhir/cr/measure/dstu3/Dstu3MeasureEvaluatorSingle.java
index 6c1a632164..9900210ec7 100644
--- a/cqf-fhir-cr/src/main/java/org/opencds/cqf/fhir/cr/measure/dstu3/Dstu3MeasureEvaluatorSingle.java
+++ b/cqf-fhir-cr/src/main/java/org/opencds/cqf/fhir/cr/measure/dstu3/Dstu3MeasureEvaluatorSingle.java
@@ -1,7 +1,5 @@
package org.opencds.cqf.fhir.cr.measure.dstu3;
-import org.hl7.fhir.dstu3.model.Bundle;
-import org.hl7.fhir.dstu3.model.Endpoint;
import org.hl7.fhir.dstu3.model.IdType;
import org.hl7.fhir.dstu3.model.MeasureReport;
import org.hl7.fhir.dstu3.model.Parameters;
@@ -21,7 +19,5 @@ MeasureReport evaluateMeasure(
String practitioner,
String lastReceivedOn,
String productLine,
- Bundle additionalData,
- Parameters parameters,
- Endpoint terminologyEndpoint);
+ Parameters parameters);
}
diff --git a/cqf-fhir-cr/src/main/java/org/opencds/cqf/fhir/cr/measure/dstu3/Dstu3MeasureService.java b/cqf-fhir-cr/src/main/java/org/opencds/cqf/fhir/cr/measure/dstu3/Dstu3MeasureService.java
index 285b84f71a..2b23493a41 100644
--- a/cqf-fhir-cr/src/main/java/org/opencds/cqf/fhir/cr/measure/dstu3/Dstu3MeasureService.java
+++ b/cqf-fhir-cr/src/main/java/org/opencds/cqf/fhir/cr/measure/dstu3/Dstu3MeasureService.java
@@ -12,12 +12,10 @@
import ca.uhn.fhir.util.BundleBuilder;
import java.util.Collections;
import java.util.List;
-import org.hl7.fhir.dstu3.model.Bundle;
import org.hl7.fhir.dstu3.model.CodeableConcept;
import org.hl7.fhir.dstu3.model.Coding;
import org.hl7.fhir.dstu3.model.ContactDetail;
import org.hl7.fhir.dstu3.model.ContactPoint;
-import org.hl7.fhir.dstu3.model.Endpoint;
import org.hl7.fhir.dstu3.model.Enumerations;
import org.hl7.fhir.dstu3.model.Extension;
import org.hl7.fhir.dstu3.model.IdType;
@@ -89,8 +87,7 @@ public Dstu3MeasureService(IRepository repository, MeasureEvaluationOptions meas
* received.
* @param productLine the productLine (e.g. Medicare, Medicaid, etc) to use
* for the evaluation. This is a non-standard parameter.
- * @param additionalData the data bundle containing additional data
- * @param terminologyEndpoint the endpoint of terminology services for your measure valuesets
+ * @param environment endpoint and supplemental data configuration
* @return the calculated MeasureReport
*/
@Override
@@ -103,16 +100,14 @@ public MeasureReport evaluateMeasure(
String practitioner,
String lastReceivedOn,
String productLine,
- Bundle additionalData,
- Parameters parameters,
- Endpoint terminologyEndpoint) {
+ Parameters parameters) {
ensureSupplementalDataElementSearchParameter();
var dstu3MeasureProcessor = new Dstu3MeasureProcessor(repository, measureEvaluationOptions);
MeasureReport report = dstu3MeasureProcessor.evaluateMeasure(
- id, periodStart, periodEnd, reportType, Collections.singletonList(subject), additionalData, parameters);
+ id, periodStart, periodEnd, reportType, Collections.singletonList(subject), null, parameters);
if (productLine != null) {
Extension ext = new Extension();
diff --git a/cqf-fhir-cr/src/main/java/org/opencds/cqf/fhir/cr/measure/r4/R4CareGapsBundleBuilder.java b/cqf-fhir-cr/src/main/java/org/opencds/cqf/fhir/cr/measure/r4/R4CareGapsBundleBuilder.java
index c8aad3a974..8398a969ff 100644
--- a/cqf-fhir-cr/src/main/java/org/opencds/cqf/fhir/cr/measure/r4/R4CareGapsBundleBuilder.java
+++ b/cqf-fhir-cr/src/main/java/org/opencds/cqf/fhir/cr/measure/r4/R4CareGapsBundleBuilder.java
@@ -113,10 +113,6 @@ public List The critical invariant: a ProxyRepository must be created whenever any endpoint is
+ * provided, not only when all three are present. {@code Repositories.proxy()} already handles null
+ * per-endpoint entries by falling back to the local repository.
+ */
+class MeasureEnvironmentTest {
+
+ private static IRepository base;
+
+ // A real Endpoint is needed because Repositories.proxy() dispatches on fhirContext() and
+ // passes the endpoint to Clients.forEndpoint(). Client construction is lazy (no network call),
+ // so a stub address is safe in unit tests.
+ private static Endpoint dataEndpoint;
+ private static Endpoint contentEndpoint;
+ private static Endpoint terminologyEndpoint;
+
+ @BeforeAll
+ static void setup() {
+ base = new InMemoryFhirRepository(FhirContext.forR4Cached());
+ dataEndpoint = new Endpoint().setAddress("http://data.example.org/fhir");
+ contentEndpoint = new Endpoint().setAddress("http://content.example.org/fhir");
+ terminologyEndpoint = new Endpoint().setAddress("http://terminology.example.org/fhir");
+ }
+
+ // ── no-op cases ──────────────────────────────────────────────────────────
+
+ @Test
+ void resolve_emptyEnvironment_returnsBaseUnchanged() {
+ IRepository result = MeasureEnvironment.EMPTY.resolve(base);
+ assertSame(base, result, "EMPTY environment should return the base repository as-is");
+ }
+
+ @Test
+ void resolve_allEndpointsNull_noAdditionalData_returnsBaseUnchanged() {
+ var env = new MeasureEnvironment(null, null, null, null);
+ assertSame(base, env.resolve(base));
+ }
+
+ // ── single-endpoint cases (the cases the AND bug broke) ──────────────────
+
+ @Test
+ void resolve_onlyDataEndpoint_returnsProxyRepository() {
+ var env = new MeasureEnvironment(null, null, dataEndpoint, null);
+ assertInstanceOf(ProxyRepository.class, env.resolve(base));
+ }
+
+ @Test
+ void resolve_onlyContentEndpoint_returnsProxyRepository() {
+ var env = new MeasureEnvironment(contentEndpoint, null, null, null);
+ assertInstanceOf(ProxyRepository.class, env.resolve(base));
+ }
+
+ @Test
+ void resolve_onlyTerminologyEndpoint_returnsProxyRepository() {
+ var env = new MeasureEnvironment(null, terminologyEndpoint, null, null);
+ assertInstanceOf(ProxyRepository.class, env.resolve(base));
+ }
+
+ // ── all-endpoints case (worked before, must still work) ──────────────────
+
+ @Test
+ void resolve_allEndpoints_returnsProxyRepository() {
+ var env = new MeasureEnvironment(contentEndpoint, terminologyEndpoint, dataEndpoint, null);
+ assertInstanceOf(ProxyRepository.class, env.resolve(base));
+ }
+
+ // ── additionalData only ───────────────────────────────────────────────────
+
+ @Test
+ void resolve_onlyAdditionalData_returnsFederatedRepository() {
+ Bundle bundle = bundleWithPatient("p1");
+ var env = new MeasureEnvironment(null, null, null, bundle);
+ assertInstanceOf(FederatedRepository.class, env.resolve(base));
+ }
+
+ // ── endpoints + additionalData ────────────────────────────────────────────
+
+ @Test
+ void resolve_endpointsAndAdditionalData_returnsFederatedRepository() {
+ // FederatedRepository wraps the ProxyRepository; the outer type is FederatedRepository.
+ Bundle bundle = bundleWithPatient("p2");
+ var env = new MeasureEnvironment(contentEndpoint, terminologyEndpoint, dataEndpoint, bundle);
+ assertInstanceOf(FederatedRepository.class, env.resolve(base));
+ }
+
+ @Test
+ void resolve_singleEndpointAndAdditionalData_returnsFederatedRepository() {
+ Bundle bundle = bundleWithPatient("p3");
+ var env = new MeasureEnvironment(null, null, dataEndpoint, bundle);
+ assertInstanceOf(FederatedRepository.class, env.resolve(base));
+ }
+
+ // ── helpers ───────────────────────────────────────────────────────────────
+
+ private static Bundle bundleWithPatient(String id) {
+ var bundle = new Bundle();
+ bundle.setType(Bundle.BundleType.COLLECTION);
+ bundle.addEntry().setResource(new Patient().setId(id));
+ return bundle;
+ }
+}
diff --git a/cqf-fhir-cr/src/test/java/org/opencds/cqf/fhir/cr/measure/r4/Measure.java b/cqf-fhir-cr/src/test/java/org/opencds/cqf/fhir/cr/measure/r4/Measure.java
index f8db8d3025..73cf093aa4 100644
--- a/cqf-fhir-cr/src/test/java/org/opencds/cqf/fhir/cr/measure/r4/Measure.java
+++ b/cqf-fhir-cr/src/test/java/org/opencds/cqf/fhir/cr/measure/r4/Measure.java
@@ -25,6 +25,7 @@
import org.opencds.cqf.fhir.cql.engine.retrieve.RetrieveSettings.TERMINOLOGY_FILTER_MODE;
import org.opencds.cqf.fhir.cql.engine.terminology.TerminologySettings.VALUESET_EXPANSION_MODE;
import org.opencds.cqf.fhir.cr.measure.MeasureEvaluationOptions;
+import org.opencds.cqf.fhir.cr.measure.common.MeasureEnvironment;
import org.opencds.cqf.fhir.cr.measure.common.MeasurePeriodValidator;
import org.opencds.cqf.fhir.cr.measure.common.MeasureReference;
import org.opencds.cqf.fhir.cr.measure.r4.selected.def.SelectedMeasureDef;
@@ -234,10 +235,8 @@ public When evaluate() {
reportType,
subject,
null,
- null,
- null,
- null,
- additionalData,
+ new MeasureEnvironment(null, null, null, additionalData)
+ .resolve(multiMeasureService.getRepository()),
parameters,
productLine,
practitioner);
diff --git a/cqf-fhir-cr/src/test/java/org/opencds/cqf/fhir/cr/measure/r4/MultiMeasure.java b/cqf-fhir-cr/src/test/java/org/opencds/cqf/fhir/cr/measure/r4/MultiMeasure.java
index 181c22bef4..5b0e0f838e 100644
--- a/cqf-fhir-cr/src/test/java/org/opencds/cqf/fhir/cr/measure/r4/MultiMeasure.java
+++ b/cqf-fhir-cr/src/test/java/org/opencds/cqf/fhir/cr/measure/r4/MultiMeasure.java
@@ -46,6 +46,7 @@
import org.opencds.cqf.fhir.cql.engine.retrieve.RetrieveSettings.TERMINOLOGY_FILTER_MODE;
import org.opencds.cqf.fhir.cql.engine.terminology.TerminologySettings.VALUESET_EXPANSION_MODE;
import org.opencds.cqf.fhir.cr.measure.MeasureEvaluationOptions;
+import org.opencds.cqf.fhir.cr.measure.common.MeasureEnvironment;
import org.opencds.cqf.fhir.cr.measure.common.MeasurePeriodValidator;
import org.opencds.cqf.fhir.cr.measure.common.MeasureReference;
import org.opencds.cqf.fhir.cr.measure.constant.MeasureConstants;
@@ -256,10 +257,7 @@ public MultiMeasure.When evaluate() {
periodEnd,
reportType,
subject,
- null,
- null,
- null,
- additionalData,
+ new MeasureEnvironment(null, null, null, additionalData).resolve(service.getRepository()),
parameters,
productLine,
reporter);
> evaluateToListOfList(
@Nullable ZonedDateTime periodEnd,
String reportType,
String subject,
- Endpoint contentEndpoint,
- Endpoint terminologyEndpoint,
- Endpoint dataEndpoint,
- Bundle additionalData,
+ IRepository resolvedRepo,
Parameters parameters,
String productLine,
String reporter,
@@ -269,19 +229,8 @@ private List
> evaluateToListOfList(
measurePeriodValidator.validatePeriodStartAndEnd(periodStart, periodEnd);
- final R4MeasureProcessor r4ProcessorToUse;
- final R4MeasureServiceUtils r4MeasureServiceUtilsToUse;
- if (dataEndpoint != null && contentEndpoint != null && terminologyEndpoint != null) {
- var repositoryToUse =
- Repositories.proxy(repository, true, dataEndpoint, contentEndpoint, terminologyEndpoint);
-
- r4ProcessorToUse = new R4MeasureProcessor(repositoryToUse, this.measureEvaluationOptions);
-
- r4MeasureServiceUtilsToUse = new R4MeasureServiceUtils(repositoryToUse);
- } else {
- r4ProcessorToUse = r4MeasureProcessorStandardRepository;
- r4MeasureServiceUtilsToUse = r4MeasureServiceUtilsStandardRepository;
- }
+ var r4ProcessorToUse = new R4MeasureProcessor(resolvedRepo, this.measureEvaluationOptions);
+ var r4MeasureServiceUtilsToUse = new R4MeasureServiceUtils(resolvedRepo);
if (measureEvaluationOptions.isEnsureSearchParameters()) {
r4MeasureServiceUtilsToUse.ensureSupplementalDataElementSearchParameter();
@@ -309,17 +258,13 @@ private List
> evaluateToListOfList(
var evalType = r4MeasureServiceUtilsToUse.getMeasureEvalType(reportType, subjectToUse);
- // another flex point between single and multi measures
var subjects =
switch (singleOrMultiple) {
- case SINGLE -> getSubjectsForEvaluateSingle(subjectToUse, repository, additionalData);
+ case SINGLE -> getSubjectsForEvaluateSingle(subjectToUse, resolvedRepo);
case MULTIPLE -> getSubjects(subjectProvider, subjectToUse);
};
- var context = Engines.forRepository(
- r4ProcessorToUse.getRepository(),
- this.measureEvaluationOptions.getEvaluationSettings(),
- additionalData);
+ var context = Engines.forRepository(resolvedRepo, this.measureEvaluationOptions.getEvaluationSettings(), null);
final CompositeEvaluationResultsPerMeasure compositeEvaluationResultsPerMeasure =
r4ProcessorToUse.evaluateMultiMeasuresWithCqlEngine(
@@ -589,19 +534,10 @@ protected Bundle.BundleEntryComponent getBundleEntry(String serverBase, Resource
}
@Nonnull
- private List