Skip to content

Commit

Permalink
Merge pull request #83 from MeasureAuthoringTool/MAT-7223/updateLogic…
Browse files Browse the repository at this point in the history
…ForCheckingExistingCqlMetaData

Mat 7223/update logic for checking existing cql meta data
  • Loading branch information
sb-prateekkeerthi authored May 24, 2024
2 parents 799c1da + 9393c2a commit 1d34798
Show file tree
Hide file tree
Showing 7 changed files with 121 additions and 58 deletions.
2 changes: 1 addition & 1 deletion src/main/java/gov/cms/madie/terminology/dto/Code.java
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@
public class Code {
private String name;
private String display;
private String version; // 'fhir' in the code-system-entry.json
private String fhirVersion; // 'fhir' in the code-system-entry.json
private String svsVersion; // 'vsac' in the code-system-entry.json
private String codeSystem;
private String codeSystemOid;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -128,8 +128,8 @@ public List<ValueSetForSearch> searchValueSets(String apiKey, Map<String, String
.forEach(
entry -> {
Resource resource = entry.getResource();
ValueSet vs = (ValueSet) resource;
if (resource instanceof ValueSet) {
ValueSet vs = (ValueSet) resource;
if (resource instanceof ValueSet) {
String oid = "";
for (Identifier identifier : ((ValueSet) resource).getIdentifier()) {
if (identifier.getValue() != null && !identifier.getValue().isEmpty()) {
Expand All @@ -139,17 +139,32 @@ public List<ValueSetForSearch> searchValueSets(String apiKey, Map<String, String
ValueSetForSearch valueSet =
ValueSetForSearch.builder()
.title(vs.getTitle())
.author(String.valueOf(vs.getExtensionByUrl("http://hl7.org/fhir/StructureDefinition/valueset-author").getValue()))
.author(
String.valueOf(
vs.getExtensionByUrl(
"http://hl7.org/fhir/StructureDefinition/valueset-author")
.getValue()))
.name(vs.getName())
.composedOf(vs.getCompose().getInclude().stream().map(x -> x.getSystem()).collect(Collectors.joining(",")))
.effectiveDate(String.valueOf(vs.getExtensionByUrl("http://hl7.org/fhir/StructureDefinition/valueset-effectiveDate").getValue()))
.lastReviewDate(String.valueOf(vs.getExtensionByUrl("http://hl7.org/fhir/StructureDefinition/resource-lastReviewDate").getValue()))
.lastUpdated(vs.getMeta().getLastUpdated().toString())
.composedOf(
vs.getCompose().getInclude().stream()
.map(x -> x.getSystem())
.collect(Collectors.joining(",")))
.effectiveDate(
String.valueOf(
vs.getExtensionByUrl(
"http://hl7.org/fhir/StructureDefinition/valueset-effectiveDate")
.getValue()))
.lastReviewDate(
String.valueOf(
vs.getExtensionByUrl(
"http://hl7.org/fhir/StructureDefinition/resource-lastReviewDate")
.getValue()))
.lastUpdated(vs.getMeta().getLastUpdated().toString())
.url(vs.getUrl())
.version(vs.getVersion())
.status(vs.getStatus())
.publisher(vs.getPublisher())
.purpose(vs.getPurpose())
.publisher(vs.getPublisher())
.purpose(vs.getPurpose())
.steward(vs.getPublisher())
.oid(oid)
.build();
Expand Down Expand Up @@ -219,26 +234,24 @@ public Code retrieveCode(String codeName, String codeSystemName, String version,
|| StringUtils.isEmpty(version)) {
return null;
}

CodeSystem codeSystem =
codeSystemRepository.findByNameAndVersion(codeSystemName, version).orElse(null);
if (codeSystem == null) {
return null;
}
String codeJson = fhirTerminologyServiceWebClient.getCodeResource(codeName, codeSystem, apiKey);
Parameters parameters = fhirContext.newJsonParser().parseResource(Parameters.class, codeJson);
Code code =
Code.builder()
.name(codeName)
.codeSystem(codeSystemName)
.version(version)
.display(parameters.getParameter("display").getValue().toString())
.codeSystemOid(parameters.getParameter("Oid").getValue().toString())
.build();
// FHIR terminology API doesn't support code status yet. workaround is to get it from SVS.
// TODO: remove once it is supported by fhir terminology service
CodeStatus status = vsacService.getCodeStatus(code, apiKey);
code.setStatus(status);
return code;

List<CodeSystemEntry> codeSystemEntries = mappingService.getCodeSystemEntries();
Optional<Map.Entry<String, String>> mappedVersion =
mapVersion(version, codeSystem.getOid(), codeSystemEntries, "fhirVersion");

if (mappedVersion.isPresent()) {
String vsacVersion = mappedVersion.get().getKey();
String fhirVersion = mappedVersion.get().getValue();

return retrieveCodes(codeName, codeSystemName, vsacVersion, fhirVersion, codeSystem, apiKey);
}
return null;
}

private void recursiveRetrieveCodeSystems(
Expand Down Expand Up @@ -329,22 +342,34 @@ public List<Code> retrieveCodesAndCodeSystems(List<Map<String, String>> codeList
String oid = code.get("oid") != null ? code.get("oid").replaceAll("'|'", "") : null;

Optional<Map.Entry<String, String>> mappedVersion =
mapToFhirVersion(code.get("version"), oid, codeSystemEntries);
mapVersion(code.get("version"), oid, codeSystemEntries, "svsVersion");

if (mappedVersion.isPresent()) {
String vsacVersion = mappedVersion.get().getKey();
String fhirVersion = mappedVersion.get().getValue();

if (StringUtils.isEmpty(codeName)
|| StringUtils.isEmpty(codeSystemName)
|| StringUtils.isEmpty(fhirVersion)) {
return null;
}

CodeSystem codeSystem =
codeSystemRepository.findByOidAndVersion(oid, fhirVersion).orElse(null);
if (codeSystem == null) {
return null;
}

return retrieveCodes(
codeName, codeSystemName, vsacVersion, fhirVersion, oid, apiKey);
codeName, codeSystemName, vsacVersion, fhirVersion, codeSystem, apiKey);
}
return null;
})
.collect(Collectors.toList());
}

private Optional<Map.Entry<String, String>> mapToFhirVersion(
String version, String oid, List<CodeSystemEntry> codeSystemEntries) {
private Optional<Map.Entry<String, String>> mapVersion(
String version, String oid, List<CodeSystemEntry> codeSystemEntries, String versionType) {
if (oid == null) {
return Optional.empty();
}
Expand All @@ -365,7 +390,14 @@ private Optional<Map.Entry<String, String>> mapToFhirVersion(
codeSystemEntries.stream()
.filter(codeSystemEntry -> StringUtils.equals(codeSystemEntry.getOid(), oid))
.flatMap(codeSystemEntry -> codeSystemEntry.getVersions().stream())
.filter(codeSystemVersion -> StringUtils.equals(codeSystemVersion.getVsac(), version))
// depending on the version type suitable mapping is done
.filter(
codeSystemVersion ->
StringUtils.equals(
versionType == "svsVersion"
? codeSystemVersion.getVsac()
: codeSystemVersion.getFhir(),
version))
.map(
codeSystemVersion ->
Map.entry(codeSystemVersion.getVsac(), codeSystemVersion.getFhir()))
Expand All @@ -380,25 +412,16 @@ private Code retrieveCodes(
String codeSystemName,
String vsacVersion,
String fhirVersion,
String oid,
CodeSystem codeSystem,
String apiKey) {
if (StringUtils.isEmpty(codeName)
|| StringUtils.isEmpty(codeSystemName)
|| StringUtils.isEmpty(fhirVersion)) {
return null;
}
CodeSystem codeSystem = codeSystemRepository.findByOidAndVersion(oid, fhirVersion).orElse(null);
if (codeSystem == null) {
return null;
}
String codeJson = fhirTerminologyServiceWebClient.getCodeResource(codeName, codeSystem, apiKey);

Parameters parameters = fhirContext.newJsonParser().parseResource(Parameters.class, codeJson);
Code code =
Code.builder()
.name(codeName)
.codeSystem(codeSystemName)
.version(fhirVersion)
.fhirVersion(fhirVersion)
.svsVersion(vsacVersion)
.display(parameters.getParameter("display").getValue().toString())
.codeSystemOid(parameters.getParameter("Oid").getValue().toString())
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -194,7 +194,7 @@ private String getSvsCodeSystemVersion(Code code) {
// get corresponding SVS version for given FHIR version
CodeSystemEntry.Version version =
systemEntry.getVersions().stream()
.filter(v -> Objects.equals(v.getFhir(), code.getVersion()))
.filter(v -> Objects.equals(v.getFhir(), code.getFhirVersion()))
.findFirst()
.orElse(null);
if (version == null || version.getVsac() == null) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -244,7 +244,8 @@ public void testGetCodeSuccessfully() throws Exception {
Code.builder()
.name(codeName)
.codeSystem(codeSystem)
.version(version)
.fhirVersion(version)
.svsVersion(version)
.display("Bicarbonate [Moles/volume] in Serum")
.codeSystemOid("2.16.840.1.113883.6.1")
.build();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -193,7 +193,8 @@ void testGetCode() {
Code.builder()
.name(codeName)
.codeSystem(codeSystem)
.version(version)
.svsVersion(version)
.fhirVersion(version)
.display("Bicarbonate [Moles/volume] in Serum")
.codeSystemOid("2.16.840.1.113883.6.1")
.build();
Expand Down Expand Up @@ -238,7 +239,8 @@ void testGetCodesList() {
Code.builder()
.name("1963-8")
.codeSystem("LOINC")
.version("2.72")
.svsVersion("2.72")
.fhirVersion("2.72")
.display("Bicarbonate [Moles/volume] in Serum")
.codeSystemOid("2.16.840.1.113883.6.1")
.status(CodeStatus.valueOf("ACTIVE"))
Expand All @@ -258,10 +260,26 @@ void testGetCodesList() {
@Test
void testSearchValueSets() {
List<ValueSetForSearch> mockValueSets = new ArrayList<>();
ValueSetForSearch v1 = ValueSetForSearch.builder().title("title 1").name("title1").url("url").oid("oid")
.steward("steward").version("version").codeSystem("cs").build();
ValueSetForSearch v2 = ValueSetForSearch.builder().title("title 2").name("title2").url("url").oid("oid")
.steward("steward").version("version").codeSystem("cs").build();
ValueSetForSearch v1 =
ValueSetForSearch.builder()
.title("title 1")
.name("title1")
.url("url")
.oid("oid")
.steward("steward")
.version("version")
.codeSystem("cs")
.build();
ValueSetForSearch v2 =
ValueSetForSearch.builder()
.title("title 2")
.name("title2")
.url("url")
.oid("oid")
.steward("steward")
.version("version")
.codeSystem("cs")
.build();
mockValueSets.add(v1);
mockValueSets.add(v2);
Principal principal = mock(Principal.class);
Expand All @@ -272,7 +290,7 @@ void testSearchValueSets() {
queryParams.put("param1", "value1");
queryParams.put("param2", "value2");
ResponseEntity<List<ValueSetForSearch>> response =
vsacFhirTerminologyController.searchValueSets(principal, queryParams);
vsacFhirTerminologyController.searchValueSets(principal, queryParams);
assertEquals(response.getStatusCode(), HttpStatus.OK);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -435,8 +435,29 @@ void testRetrieveCodeSuccessfully() {
+ " \"valueString\": \"2.16.840.1.113883.6.1\"\n"
+ " } ]\n"
+ "}";
codeSystemEntries = new ArrayList<>();
CodeSystemEntry.Version versions = new CodeSystemEntry.Version();
versions.setVsac("2.40");
versions.setFhir("2.40");
var codeSystemEntry =
CodeSystemEntry.builder()
.name("1963-8")
.oid("urn:oid:2.16.840.1.113883.6.1")
.url("http://loinc.org")
.versions(List.of(versions))
.build();
codeSystemEntries.add(codeSystemEntry);

var codeSystem = gov.cms.madie.terminology.models.CodeSystem.builder().build();
var codeSystem =
gov.cms.madie.terminology.models.CodeSystem.builder()
.fullUrl("http://loinc.org")
.title("LOINC")
.name("LOINC")
.version("2.40")
.versionId("2084800774")
.oid("urn:oid:2.16.840.1.113883.6.1")
.build();
when(mappingService.getCodeSystemEntries()).thenReturn(codeSystemEntries);
when(codeSystemRepository.findByNameAndVersion(anyString(), anyString()))
.thenReturn(Optional.of(codeSystem));
when(fhirTerminologyServiceWebClient.getCodeResource(codeName, codeSystem, TEST_API_KEY))
Expand All @@ -448,7 +469,7 @@ void testRetrieveCodeSuccessfully() {
assertThat(code.getName(), is(equalTo(codeName)));
assertThat(code.getDisplay(), is(equalTo("Bicarbonate [Moles/volume] in Serum")));
assertThat(code.getCodeSystem(), is(equalTo(codeSystemName)));
assertThat(code.getVersion(), is(equalTo(version)));
assertThat(code.getFhirVersion(), is(equalTo(version)));
assertThat(code.getStatus(), is(equalTo(CodeStatus.ACTIVE)));
}

Expand Down Expand Up @@ -514,7 +535,7 @@ void testRetrieveCodesListSuccessfully() {
assertThat(code.get(0).getName(), is(equalTo("1963-8")));
assertThat(code.get(0).getDisplay(), is(equalTo("Bicarbonate [Moles/volume] in Serum")));
assertThat(code.get(0).getCodeSystem(), is(equalTo("LOINC")));
assertThat(code.get(0).getVersion(), is(equalTo("2.40")));
assertThat(code.get(0).getFhirVersion(), is(equalTo("2.40")));
assertThat(code.get(0).getStatus(), is(equalTo(CodeStatus.ACTIVE)));
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -459,7 +459,7 @@ void testGetCodeStatusIfCodeSystemMappingAbsent() {
when(mappingService.getCodeSystemEntryByOid(anyString())).thenReturn(null);
assertThat(
vsacService.getCodeStatus(
Code.builder().codeSystemOid("oid").version("version").build(), TEST_API_KEY),
Code.builder().codeSystemOid("oid").fhirVersion("version").build(), TEST_API_KEY),
is(equalTo(CodeStatus.NA)));
}

Expand All @@ -469,7 +469,7 @@ void testGetCodeStatusIfCodeSystemNotInSvs() {
when(mappingService.getCodeSystemEntryByOid(anyString())).thenReturn(cse);
assertThat(
vsacService.getCodeStatus(
Code.builder().codeSystemOid("oid").version("version").build(), TEST_API_KEY),
Code.builder().codeSystemOid("oid").fhirVersion("version").build(), TEST_API_KEY),
is(equalTo(CodeStatus.NA)));
}

Expand Down Expand Up @@ -510,7 +510,7 @@ void testGetCodeStatusActive() {
Code.builder()
.name("1222766008")
.codeSystem("ABC")
.version("abc.info/20230901")
.fhirVersion("abc.info/20230901")
.display("American Joint Committee on Cancer stage IIA")
.codeSystemOid("1.2.3.4.96")
.build();
Expand Down Expand Up @@ -543,7 +543,7 @@ void testGetCodeStatusInactive() {
Code.builder()
.name("1222766008")
.codeSystem("ABC")
.version("abc.info/20230901")
.fhirVersion("abc.info/20230901")
.display("American Joint Committee on Cancer stage IIA")
.codeSystemOid("1.2.3.4.96")
.build();
Expand Down Expand Up @@ -576,7 +576,7 @@ void testGetCodeStatusIfCodeNotFoundInSvs() {
Code.builder()
.name("1222766008")
.codeSystem("ABC")
.version("abc.info/20230901")
.fhirVersion("abc.info/20230901")
.display("American Joint Committee on Cancer stage IIA")
.codeSystemOid("1.2.3.4.96")
.build();
Expand Down

0 comments on commit 1d34798

Please sign in to comment.