Skip to content

Commit 9cb665b

Browse files
authored
Add direct reference codes to manifest during $release (#665)
* Add direct reference codes to manifest during $release * Fix sonar issues * Update cqf-directReference URL constant and tests to reflect * Move constants from MeasureConstants to Constants class
1 parent d36ab2c commit 9cb665b

7 files changed

Lines changed: 143 additions & 19 deletions

File tree

cqf-fhir-cr/src/main/java/org/opencds/cqf/fhir/cr/visitor/ReleaseVisitor.java

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -376,6 +376,19 @@ private void gatherDependencies(
376376
rootAdapter.setRelatedArtifact(updatedRelatedArtifacts);
377377
}
378378
}
379+
380+
extractMeasureDirectReferenceCodes(rootAdapter, artifactAdapter);
381+
}
382+
}
383+
384+
private void extractMeasureDirectReferenceCodes(
385+
IKnowledgeArtifactAdapter rootAdapter, IKnowledgeArtifactAdapter artifactAdapter) {
386+
if (artifactAdapter instanceof org.opencds.cqf.fhir.utility.adapter.r4.MeasureAdapter measureAdapter) {
387+
org.opencds.cqf.fhir.cr.visitor.r4.ReleaseVisitor.extractDirectReferenceCodes(
388+
rootAdapter, measureAdapter.get());
389+
} else if (artifactAdapter instanceof org.opencds.cqf.fhir.utility.adapter.r5.MeasureAdapter measureAdapter) {
390+
org.opencds.cqf.fhir.cr.visitor.r5.ReleaseVisitor.extractDirectReferenceCodes(
391+
rootAdapter, measureAdapter.get());
379392
}
380393
}
381394

cqf-fhir-cr/src/main/java/org/opencds/cqf/fhir/cr/visitor/r4/ReleaseVisitor.java

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,14 +16,18 @@
1616
import org.hl7.fhir.r4.model.Bundle;
1717
import org.hl7.fhir.r4.model.Bundle.BundleEntryComponent;
1818
import org.hl7.fhir.r4.model.Extension;
19+
import org.hl7.fhir.r4.model.Library;
20+
import org.hl7.fhir.r4.model.Measure;
1921
import org.hl7.fhir.r4.model.MetadataResource;
2022
import org.hl7.fhir.r4.model.Period;
23+
import org.hl7.fhir.r4.model.Reference;
2124
import org.hl7.fhir.r4.model.ResourceType;
2225
import org.hl7.fhir.r4.model.StringType;
2326
import org.hl7.fhir.r4.model.ValueSet;
2427
import org.opencds.cqf.fhir.api.Repository;
2528
import org.opencds.cqf.fhir.cr.visitor.r4.CRMIReleaseExperimentalBehavior.CRMIReleaseExperimentalBehaviorCodes;
2629
import org.opencds.cqf.fhir.cr.visitor.r4.CRMIReleaseVersionBehavior.CRMIReleaseVersionBehaviorCodes;
30+
import org.opencds.cqf.fhir.utility.Constants;
2731
import org.opencds.cqf.fhir.utility.PackageHelper;
2832
import org.opencds.cqf.fhir.utility.SearchHelper;
2933
import org.opencds.cqf.fhir.utility.adapter.IKnowledgeArtifactAdapter;
@@ -156,4 +160,20 @@ public static List<BundleEntryComponent> findArtifactCommentsToUpdate(
156160
});
157161
return returnEntries;
158162
}
163+
164+
public static void extractDirectReferenceCodes(IKnowledgeArtifactAdapter rootAdapter, Measure measure) {
165+
Optional<Extension> effectiveDataRequirementsExt = measure.getExtension().stream()
166+
.filter(ext -> ext.getUrl().equals(Constants.CQFM_EFFECTIVE_DATA_REQUIREMENTS))
167+
.findFirst();
168+
if (effectiveDataRequirementsExt.isPresent()) {
169+
Reference ref = (Reference) effectiveDataRequirementsExt.get().getValue();
170+
Library effectiveDataRequirementsLib = (Library) measure.getContained("#" + ref.getReference());
171+
if (effectiveDataRequirementsLib != null) {
172+
effectiveDataRequirementsLib.getExtension().stream()
173+
.filter(ext -> ext.getUrl().equals(Constants.CQFM_DIRECT_REFERENCE_EXTENSION))
174+
.map(ext -> ext.setUrl(Constants.CQF_DIRECT_REFERENCE_EXTENSION))
175+
.forEach(rootAdapter::addExtension);
176+
}
177+
}
178+
}
159179
}

cqf-fhir-cr/src/main/java/org/opencds/cqf/fhir/cr/visitor/r5/ReleaseVisitor.java

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,15 +16,19 @@
1616
import org.hl7.fhir.r5.model.Bundle;
1717
import org.hl7.fhir.r5.model.Bundle.BundleEntryComponent;
1818
import org.hl7.fhir.r5.model.Extension;
19+
import org.hl7.fhir.r5.model.Library;
20+
import org.hl7.fhir.r5.model.Measure;
1921
import org.hl7.fhir.r5.model.MetadataResource;
2022
import org.hl7.fhir.r5.model.Period;
23+
import org.hl7.fhir.r5.model.Reference;
2124
import org.hl7.fhir.r5.model.RelatedArtifact.RelatedArtifactType;
2225
import org.hl7.fhir.r5.model.ResourceType;
2326
import org.hl7.fhir.r5.model.StringType;
2427
import org.hl7.fhir.r5.model.ValueSet;
2528
import org.opencds.cqf.fhir.api.Repository;
2629
import org.opencds.cqf.fhir.cr.visitor.r5.CRMIReleaseExperimentalBehavior.CRMIReleaseExperimentalBehaviorCodes;
2730
import org.opencds.cqf.fhir.cr.visitor.r5.CRMIReleaseVersionBehavior.CRMIReleaseVersionBehaviorCodes;
31+
import org.opencds.cqf.fhir.utility.Constants;
2832
import org.opencds.cqf.fhir.utility.PackageHelper;
2933
import org.opencds.cqf.fhir.utility.SearchHelper;
3034
import org.opencds.cqf.fhir.utility.adapter.IKnowledgeArtifactAdapter;
@@ -143,4 +147,19 @@ public static List<BundleEntryComponent> findArtifactCommentsToUpdate(
143147
});
144148
return returnEntries;
145149
}
150+
151+
public static void extractDirectReferenceCodes(IKnowledgeArtifactAdapter rootAdapter, Measure measure) {
152+
Optional<Extension> effectiveDataRequirementsExt = measure.getExtension().stream()
153+
.filter(ext -> ext.getUrl().equals(Constants.CQFM_EFFECTIVE_DATA_REQUIREMENTS))
154+
.findFirst();
155+
if (effectiveDataRequirementsExt.isPresent()) {
156+
Reference ref = effectiveDataRequirementsExt.get().getValueReference();
157+
Library effectiveDataRequirementsLib = (Library) measure.getContained("#" + ref.getReference());
158+
if (effectiveDataRequirementsLib != null) {
159+
effectiveDataRequirementsLib.getExtension().stream()
160+
.filter(ext -> ext.getUrl().equals(Constants.CQF_DIRECT_REFERENCE_EXTENSION))
161+
.forEach(rootAdapter::addExtension);
162+
}
163+
}
164+
}
146165
}

cqf-fhir-cr/src/test/java/org/opencds/cqf/fhir/cr/visitor/r4/ReleaseVisitorTests.java

Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -252,6 +252,40 @@ void bothCRMIandCQFMEffectiveDataRequirementsTest() {
252252
assertEquals(2, componentsOnReleasedArtifact.size());
253253
}
254254

255+
@Test
256+
void measureDirectReferenceCodesIncludedInReleaseTest() {
257+
Bundle bundle = (Bundle) jsonParser.parseResource(
258+
ReleaseVisitorTests.class.getResourceAsStream("Bundle-ecqm-qicore-2024-simplified.json"));
259+
repo.transaction(bundle);
260+
Library library = repo.read(Library.class, new IdType("Library/ecqm-update-2024-05-02"))
261+
.copy();
262+
ILibraryAdapter libraryAdapter = new AdapterFactory().createLibrary(library);
263+
Parameters params = new Parameters();
264+
params.addParameter("version", "1.0.0");
265+
params.addParameter("versionBehavior", new CodeType("default"));
266+
var crmiEDRId = "exp-params-crmi-test";
267+
var crmiEDRExtension = new Extension();
268+
crmiEDRExtension.setUrl(Constants.CRMI_EFFECTIVE_DATA_REQUIREMENTS);
269+
crmiEDRExtension.setValue(new CanonicalType("#" + crmiEDRId));
270+
ReleaseVisitor releaseVisitor = new ReleaseVisitor(repo);
271+
// Approval date is required to release an artifact
272+
library.setApprovalDateElement(new DateType("2024-04-23"));
273+
274+
Bundle returnResource = (Bundle) libraryAdapter.accept(releaseVisitor, params);
275+
assertNotNull(returnResource);
276+
Optional<BundleEntryComponent> maybeLib = returnResource.getEntry().stream()
277+
.filter(entry -> entry.getResponse().getLocation().contains("Library"))
278+
.findFirst();
279+
assertTrue(maybeLib.isPresent());
280+
Library releasedLibrary =
281+
repo.read(Library.class, new IdType(maybeLib.get().getResponse().getLocation()));
282+
var directReferenceExtensions = releasedLibrary.getExtension().stream()
283+
.filter(ext -> ext.getUrl().equals(Constants.CQF_DIRECT_REFERENCE_EXTENSION))
284+
.toList();
285+
286+
assertEquals(18, directReferenceExtensions.size());
287+
}
288+
255289
@Test
256290
void visitLibraryTest() {
257291
Bundle bundle = (Bundle) jsonParser.parseResource(

cqf-fhir-cr/src/test/java/org/opencds/cqf/fhir/cr/visitor/r5/ReleaseVisitorTests.java

Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -252,6 +252,41 @@ void bothCRMIandCQFMEffectiveDataRequirementsTest() {
252252
assertEquals(2, componentsOnReleasedArtifact.size());
253253
}
254254

255+
@Test
256+
void measureDirectReferenceCodesIncludedInReleaseTest() {
257+
Bundle bundle = (Bundle) jsonParser.parseResource(
258+
org.opencds.cqf.fhir.cr.visitor.r5.ReleaseVisitorTests.class.getResourceAsStream(
259+
"Bundle-ecqm-qicore-2024-simplified.json"));
260+
repo.transaction(bundle);
261+
Library library = repo.read(Library.class, new IdType("Library/ecqm-update-2024-05-02"))
262+
.copy();
263+
ILibraryAdapter libraryAdapter = new AdapterFactory().createLibrary(library);
264+
Parameters params = new Parameters();
265+
params.addParameter("version", "1.0.0");
266+
params.addParameter("versionBehavior", new CodeType("default"));
267+
var crmiEDRId = "exp-params-crmi-test";
268+
var crmiEDRExtension = new Extension();
269+
crmiEDRExtension.setUrl(Constants.CRMI_EFFECTIVE_DATA_REQUIREMENTS);
270+
crmiEDRExtension.setValue(new CanonicalType("#" + crmiEDRId));
271+
ReleaseVisitor releaseVisitor = new ReleaseVisitor(repo);
272+
// Approval date is required to release an artifact
273+
library.setApprovalDateElement(new DateType("2024-04-23"));
274+
275+
Bundle returnResource = (Bundle) libraryAdapter.accept(releaseVisitor, params);
276+
assertNotNull(returnResource);
277+
Optional<Bundle.BundleEntryComponent> maybeLib = returnResource.getEntry().stream()
278+
.filter(entry -> entry.getResponse().getLocation().contains("Library"))
279+
.findFirst();
280+
assertTrue(maybeLib.isPresent());
281+
Library releasedLibrary =
282+
repo.read(Library.class, new IdType(maybeLib.get().getResponse().getLocation()));
283+
var directReferenceExtensions = releasedLibrary.getExtension().stream()
284+
.filter(ext -> ext.getUrl().equals(Constants.CQF_DIRECT_REFERENCE_EXTENSION))
285+
.toList();
286+
287+
assertEquals(18, directReferenceExtensions.size());
288+
}
289+
255290
@Test
256291
void visitLibraryTest() {
257292
Bundle bundle = (Bundle) jsonParser.parseResource(

cqf-fhir-cr/src/test/resources/org/opencds/cqf/fhir/cr/visitor/r5/Bundle-ecqm-qicore-2024-simplified.json

Lines changed: 18 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -209,55 +209,55 @@
209209
"id": "effective-data-requirements",
210210
"extension": [
211211
{
212-
"url": "http://hl7.org/fhir/us/cqfmeasures/StructureDefinition/cqfm-directReferenceCode",
212+
"url": "http://hl7.org/fhir/StructureDefinition/cqf-directReferenceCode",
213213
"valueCoding": {
214214
"system": "http://terminology.hl7.org/CodeSystem/observation-category",
215215
"code": "laboratory",
216216
"display": "laboratory"
217217
}
218218
},
219219
{
220-
"url": "http://hl7.org/fhir/us/cqfmeasures/StructureDefinition/cqfm-directReferenceCode",
220+
"url": "http://hl7.org/fhir/StructureDefinition/cqf-directReferenceCode",
221221
"valueCoding": {
222222
"system": "http://snomed.info/sct",
223223
"code": "428361000124107",
224224
"display": "Discharge to home for hospice care (procedure)"
225225
}
226226
},
227227
{
228-
"url": "http://hl7.org/fhir/us/cqfmeasures/StructureDefinition/cqfm-directReferenceCode",
228+
"url": "http://hl7.org/fhir/StructureDefinition/cqf-directReferenceCode",
229229
"valueCoding": {
230230
"system": "http://snomed.info/sct",
231231
"code": "428371000124100",
232232
"display": "Discharge to healthcare facility for hospice care (procedure)"
233233
}
234234
},
235235
{
236-
"url": "http://hl7.org/fhir/us/cqfmeasures/StructureDefinition/cqfm-directReferenceCode",
236+
"url": "http://hl7.org/fhir/StructureDefinition/cqf-directReferenceCode",
237237
"valueCoding": {
238238
"system": "http://terminology.hl7.org/CodeSystem/observation-category",
239239
"code": "survey",
240240
"display": "survey"
241241
}
242242
},
243243
{
244-
"url": "http://hl7.org/fhir/us/cqfmeasures/StructureDefinition/cqfm-directReferenceCode",
244+
"url": "http://hl7.org/fhir/StructureDefinition/cqf-directReferenceCode",
245245
"valueCoding": {
246246
"system": "http://snomed.info/sct",
247247
"code": "373066001",
248248
"display": "Yes (qualifier value)"
249249
}
250250
},
251251
{
252-
"url": "http://hl7.org/fhir/us/cqfmeasures/StructureDefinition/cqfm-directReferenceCode",
252+
"url": "http://hl7.org/fhir/StructureDefinition/cqf-directReferenceCode",
253253
"valueCoding": {
254254
"system": "http://loinc.org",
255255
"code": "45755-6",
256256
"display": "Hospice care [Minimum Data Set]"
257257
}
258258
},
259259
{
260-
"url": "http://hl7.org/fhir/us/cqfmeasures/StructureDefinition/cqfm-directReferenceCode",
260+
"url": "http://hl7.org/fhir/StructureDefinition/cqf-directReferenceCode",
261261
"valueCoding": {
262262
"system": "http://loinc.org",
263263
"code": "71007-9",
@@ -2145,87 +2145,87 @@
21452145
"id": "effective-data-requirements",
21462146
"extension": [
21472147
{
2148-
"url": "http://hl7.org/fhir/us/cqfmeasures/StructureDefinition/cqfm-directReferenceCode",
2148+
"url": "http://hl7.org/fhir/StructureDefinition/cqf-directReferenceCode",
21492149
"valueCoding": {
21502150
"system": "http://snomed.info/sct",
21512151
"code": "428361000124107",
21522152
"display": "Discharge to home for hospice care (procedure)"
21532153
}
21542154
},
21552155
{
2156-
"url": "http://hl7.org/fhir/us/cqfmeasures/StructureDefinition/cqfm-directReferenceCode",
2156+
"url": "http://hl7.org/fhir/StructureDefinition/cqf-directReferenceCode",
21572157
"valueCoding": {
21582158
"system": "http://snomed.info/sct",
21592159
"code": "428371000124100",
21602160
"display": "Discharge to healthcare facility for hospice care (procedure)"
21612161
}
21622162
},
21632163
{
2164-
"url": "http://hl7.org/fhir/us/cqfmeasures/StructureDefinition/cqfm-directReferenceCode",
2164+
"url": "http://hl7.org/fhir/StructureDefinition/cqf-directReferenceCode",
21652165
"valueCoding": {
21662166
"system": "http://terminology.hl7.org/CodeSystem/observation-category",
21672167
"code": "survey",
21682168
"display": "survey"
21692169
}
21702170
},
21712171
{
2172-
"url": "http://hl7.org/fhir/us/cqfmeasures/StructureDefinition/cqfm-directReferenceCode",
2172+
"url": "http://hl7.org/fhir/StructureDefinition/cqf-directReferenceCode",
21732173
"valueCoding": {
21742174
"system": "http://snomed.info/sct",
21752175
"code": "373066001",
21762176
"display": "Yes (qualifier value)"
21772177
}
21782178
},
21792179
{
2180-
"url": "http://hl7.org/fhir/us/cqfmeasures/StructureDefinition/cqfm-directReferenceCode",
2180+
"url": "http://hl7.org/fhir/StructureDefinition/cqf-directReferenceCode",
21812181
"valueCoding": {
21822182
"system": "http://loinc.org",
21832183
"code": "45755-6",
21842184
"display": "Hospice care [Minimum Data Set]"
21852185
}
21862186
},
21872187
{
2188-
"url": "http://hl7.org/fhir/us/cqfmeasures/StructureDefinition/cqfm-directReferenceCode",
2188+
"url": "http://hl7.org/fhir/StructureDefinition/cqf-directReferenceCode",
21892189
"valueCoding": {
21902190
"system": "http://snomed.info/sct",
21912191
"code": "24028007",
21922192
"display": "Right (qualifier value)"
21932193
}
21942194
},
21952195
{
2196-
"url": "http://hl7.org/fhir/us/cqfmeasures/StructureDefinition/cqfm-directReferenceCode",
2196+
"url": "http://hl7.org/fhir/StructureDefinition/cqf-directReferenceCode",
21972197
"valueCoding": {
21982198
"system": "http://snomed.info/sct",
21992199
"code": "7771000",
22002200
"display": "Left (qualifier value)"
22012201
}
22022202
},
22032203
{
2204-
"url": "http://hl7.org/fhir/us/cqfmeasures/StructureDefinition/cqfm-directReferenceCode",
2204+
"url": "http://hl7.org/fhir/StructureDefinition/cqf-directReferenceCode",
22052205
"valueCoding": {
22062206
"system": "http://loinc.org",
22072207
"code": "98181-1",
22082208
"display": "Medical equipment used"
22092209
}
22102210
},
22112211
{
2212-
"url": "http://hl7.org/fhir/us/cqfmeasures/StructureDefinition/cqfm-directReferenceCode",
2212+
"url": "http://hl7.org/fhir/StructureDefinition/cqf-directReferenceCode",
22132213
"valueCoding": {
22142214
"system": "http://loinc.org",
22152215
"code": "71802-3",
22162216
"display": "Housing status"
22172217
}
22182218
},
22192219
{
2220-
"url": "http://hl7.org/fhir/us/cqfmeasures/StructureDefinition/cqfm-directReferenceCode",
2220+
"url": "http://hl7.org/fhir/StructureDefinition/cqf-directReferenceCode",
22212221
"valueCoding": {
22222222
"system": "http://snomed.info/sct",
22232223
"code": "160734000",
22242224
"display": "Lives in a nursing home (finding)"
22252225
}
22262226
},
22272227
{
2228-
"url": "http://hl7.org/fhir/us/cqfmeasures/StructureDefinition/cqfm-directReferenceCode",
2228+
"url": "http://hl7.org/fhir/StructureDefinition/cqf-directReferenceCode",
22292229
"valueCoding": {
22302230
"system": "http://loinc.org",
22312231
"code": "71007-9",

cqf-fhir-utility/src/main/java/org/opencds/cqf/fhir/utility/Constants.java

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -88,6 +88,8 @@ public enum CqfApplicabilityBehavior {
8888
public static final String CQF_LIBRARY = "http://hl7.org/fhir/StructureDefinition/cqf-library";
8989
public static final String CQF_CALCULATED_VALUE = "http://hl7.org/fhir/StructureDefinition/cqf-calculatedValue";
9090
public static final String CQF_FHIR_QUERY_PATTERN = "http://hl7.org/fhir/StructureDefinition/cqf-fhirQueryPattern";
91+
public static final String CQF_DIRECT_REFERENCE_EXTENSION =
92+
"http://hl7.org/fhir/StructureDefinition/cqf-directReferenceCode";
9193

9294
public static final String CQFM_EFFECTIVE_DATA_REQUIREMENTS =
9395
"http://hl7.org/fhir/us/cqfmeasures/StructureDefinition/cqfm-effectiveDataRequirements";
@@ -98,7 +100,8 @@ public enum CqfApplicabilityBehavior {
98100
public static final String CQFM_INPUT_PARAMETERS =
99101
"http://hl7.org/fhir/us/cqfmeasures/StructureDefinition/cqfm-inputParameters";
100102
public static final String CQFM_COMPONENT = "http://hl7.org/fhir/us/cqfmeasures/StructureDefinition/cqfm-component";
101-
103+
public static final String CQFM_DIRECT_REFERENCE_EXTENSION =
104+
"http://hl7.org/fhir/us/cqfmeasures/StructureDefinition/cqfm-directReferenceCode";
102105
public static final String CRMI_EFFECTIVE_DATA_REQUIREMENTS =
103106
"http://hl7.org/fhir/uv/crmi/StructureDefinition/crmi-effectiveDataRequirements";
104107

0 commit comments

Comments
 (0)