Merge pull request #2120 from jamesagnew/im_20201005_loincpartlink_fix

Im 20201005 loincpartlink fix
This commit is contained in:
IanMMarshall 2020-10-07 12:07:23 -04:00 committed by GitHub
commit ebbdafb107
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
10 changed files with 249 additions and 16 deletions

View File

@ -21,6 +21,7 @@ package ca.uhn.fhir.jpa.term;
*/ */
import ca.uhn.fhir.jpa.term.api.ITermLoaderSvc; import ca.uhn.fhir.jpa.term.api.ITermLoaderSvc;
import ca.uhn.fhir.jpa.util.LogicUtil;
import ca.uhn.fhir.rest.server.exceptions.InternalErrorException; import ca.uhn.fhir.rest.server.exceptions.InternalErrorException;
import ca.uhn.fhir.rest.server.exceptions.UnprocessableEntityException; import ca.uhn.fhir.rest.server.exceptions.UnprocessableEntityException;
import org.apache.commons.io.FileUtils; import org.apache.commons.io.FileUtils;
@ -31,6 +32,7 @@ import org.slf4j.LoggerFactory;
import java.io.*; import java.io.*;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashSet; import java.util.HashSet;
import java.util.List; import java.util.List;
import java.util.Set; import java.util.Set;
@ -140,6 +142,24 @@ public class LoadedFileDescriptors implements Closeable {
} }
} }
void verifyPartLinkFilesExist(List<String> theMultiPartLinkFiles, String theSinglePartLinkFile) {
List<String> notFoundMulti = notFound(theMultiPartLinkFiles);
List<String> notFoundSingle = notFound(Arrays.asList(theSinglePartLinkFile));
// Expect all of the files in theMultiPartLinkFiles to be found and theSinglePartLinkFile to not be found,
// or none of the files in theMultiPartLinkFiles to be found and the SinglePartLinkFile to be found.
boolean multiPartFilesFound = notFoundMulti.isEmpty();
boolean singlePartFilesFound = notFoundSingle.isEmpty();
if (!LogicUtil.multiXor(multiPartFilesFound, singlePartFilesFound)) {
String msg;
if (!multiPartFilesFound && !singlePartFilesFound) {
msg = "Could not find any of the PartLink files: " + notFoundMulti + " nor " + notFoundSingle;
} else {
msg = "Only either the single PartLink file or the split PartLink files can be present. Found both the single PartLink file, " + theSinglePartLinkFile + ", and the split PartLink files: " + theMultiPartLinkFiles;
}
throw new UnprocessableEntityException(msg);
}
}
private static class NonClosableBOMInputStream extends BOMInputStream { private static class NonClosableBOMInputStream extends BOMInputStream {
NonClosableBOMInputStream(InputStream theWrap) { NonClosableBOMInputStream(InputStream theWrap) {

View File

@ -114,8 +114,6 @@ public class TermLoaderSvcImpl implements ITermLoaderSvc {
uploadProperties.getProperty(LOINC_IEEE_MEDICAL_DEVICE_CODE_MAPPING_TABLE_FILE.getCode(), LOINC_IEEE_MEDICAL_DEVICE_CODE_MAPPING_TABLE_FILE_DEFAULT.getCode()), uploadProperties.getProperty(LOINC_IEEE_MEDICAL_DEVICE_CODE_MAPPING_TABLE_FILE.getCode(), LOINC_IEEE_MEDICAL_DEVICE_CODE_MAPPING_TABLE_FILE_DEFAULT.getCode()),
uploadProperties.getProperty(LOINC_IMAGING_DOCUMENT_CODES_FILE.getCode(), LOINC_IMAGING_DOCUMENT_CODES_FILE_DEFAULT.getCode()), uploadProperties.getProperty(LOINC_IMAGING_DOCUMENT_CODES_FILE.getCode(), LOINC_IMAGING_DOCUMENT_CODES_FILE_DEFAULT.getCode()),
uploadProperties.getProperty(LOINC_PART_FILE.getCode(), LOINC_PART_FILE_DEFAULT.getCode()), uploadProperties.getProperty(LOINC_PART_FILE.getCode(), LOINC_PART_FILE_DEFAULT.getCode()),
uploadProperties.getProperty(LOINC_PART_LINK_FILE_PRIMARY.getCode(), LOINC_PART_LINK_FILE_PRIMARY_DEFAULT.getCode()),
uploadProperties.getProperty(LOINC_PART_LINK_FILE_SUPPLEMENTARY.getCode(), LOINC_PART_LINK_FILE_SUPPLEMENTARY_DEFAULT.getCode()),
uploadProperties.getProperty(LOINC_PART_RELATED_CODE_MAPPING_FILE.getCode(), LOINC_PART_RELATED_CODE_MAPPING_FILE_DEFAULT.getCode()), uploadProperties.getProperty(LOINC_PART_RELATED_CODE_MAPPING_FILE.getCode(), LOINC_PART_RELATED_CODE_MAPPING_FILE_DEFAULT.getCode()),
uploadProperties.getProperty(LOINC_RSNA_PLAYBOOK_FILE.getCode(), LOINC_RSNA_PLAYBOOK_FILE_DEFAULT.getCode()), uploadProperties.getProperty(LOINC_RSNA_PLAYBOOK_FILE.getCode(), LOINC_RSNA_PLAYBOOK_FILE_DEFAULT.getCode()),
uploadProperties.getProperty(LOINC_TOP2000_COMMON_LAB_RESULTS_SI_FILE.getCode(), LOINC_TOP2000_COMMON_LAB_RESULTS_SI_FILE_DEFAULT.getCode()), uploadProperties.getProperty(LOINC_TOP2000_COMMON_LAB_RESULTS_SI_FILE.getCode(), LOINC_TOP2000_COMMON_LAB_RESULTS_SI_FILE_DEFAULT.getCode()),
@ -124,6 +122,12 @@ public class TermLoaderSvcImpl implements ITermLoaderSvc {
); );
descriptors.verifyMandatoryFilesExist(mandatoryFilenameFragments); descriptors.verifyMandatoryFilesExist(mandatoryFilenameFragments);
List<String> splitPartLinkFilenameFragments = Arrays.asList(
uploadProperties.getProperty(LOINC_PART_LINK_FILE_PRIMARY.getCode(), LOINC_PART_LINK_FILE_PRIMARY_DEFAULT.getCode()),
uploadProperties.getProperty(LOINC_PART_LINK_FILE_SUPPLEMENTARY.getCode(), LOINC_PART_LINK_FILE_SUPPLEMENTARY_DEFAULT.getCode())
);
descriptors.verifyPartLinkFilesExist(splitPartLinkFilenameFragments, uploadProperties.getProperty(LOINC_PART_LINK_FILE.getCode(), LOINC_PART_LINK_FILE_DEFAULT.getCode()));
List<String> optionalFilenameFragments = Arrays.asList( List<String> optionalFilenameFragments = Arrays.asList(
uploadProperties.getProperty(LOINC_GROUP_FILE.getCode(), LOINC_GROUP_FILE_DEFAULT.getCode()), uploadProperties.getProperty(LOINC_GROUP_FILE.getCode(), LOINC_GROUP_FILE_DEFAULT.getCode()),
uploadProperties.getProperty(LOINC_GROUP_TERMS_FILE.getCode(), LOINC_GROUP_TERMS_FILE_DEFAULT.getCode()), uploadProperties.getProperty(LOINC_GROUP_TERMS_FILE.getCode(), LOINC_GROUP_TERMS_FILE_DEFAULT.getCode()),
@ -475,8 +479,9 @@ public class TermLoaderSvcImpl implements ITermLoaderSvc {
// Part link // Part link
handler = new LoincPartLinkHandler(codeSystemVersion, code2concept, propertyNamesToTypes); handler = new LoincPartLinkHandler(codeSystemVersion, code2concept, propertyNamesToTypes);
iterateOverZipFile(theDescriptors, theUploadProperties.getProperty(LOINC_PART_LINK_FILE_PRIMARY.getCode(), LOINC_PART_LINK_FILE_PRIMARY_DEFAULT.getCode()), handler, ',', QuoteMode.NON_NUMERIC, false); iterateOverZipFileOptional(theDescriptors, theUploadProperties.getProperty(LOINC_PART_LINK_FILE.getCode(), LOINC_PART_LINK_FILE_DEFAULT.getCode()), handler, ',', QuoteMode.NON_NUMERIC, false);
iterateOverZipFile(theDescriptors, theUploadProperties.getProperty(LOINC_PART_LINK_FILE_SUPPLEMENTARY.getCode(), LOINC_PART_LINK_FILE_SUPPLEMENTARY_DEFAULT.getCode()), handler, ',', QuoteMode.NON_NUMERIC, false); iterateOverZipFileOptional(theDescriptors, theUploadProperties.getProperty(LOINC_PART_LINK_FILE_PRIMARY.getCode(), LOINC_PART_LINK_FILE_PRIMARY_DEFAULT.getCode()), handler, ',', QuoteMode.NON_NUMERIC, false);
iterateOverZipFileOptional(theDescriptors, theUploadProperties.getProperty(LOINC_PART_LINK_FILE_SUPPLEMENTARY.getCode(), LOINC_PART_LINK_FILE_SUPPLEMENTARY_DEFAULT.getCode()), handler, ',', QuoteMode.NON_NUMERIC, false);
IOUtils.closeQuietly(theDescriptors); IOUtils.closeQuietly(theDescriptors);
@ -598,6 +603,14 @@ public class TermLoaderSvcImpl implements ITermLoaderSvc {
} }
public static void iterateOverZipFile(LoadedFileDescriptors theDescriptors, String theFileNamePart, IRecordHandler theHandler, char theDelimiter, QuoteMode theQuoteMode, boolean theIsPartialFilename) { public static void iterateOverZipFile(LoadedFileDescriptors theDescriptors, String theFileNamePart, IRecordHandler theHandler, char theDelimiter, QuoteMode theQuoteMode, boolean theIsPartialFilename) {
iterateOverZipFile(theDescriptors, theFileNamePart, theHandler, theDelimiter, theQuoteMode, theIsPartialFilename, true);
}
public static void iterateOverZipFileOptional(LoadedFileDescriptors theDescriptors, String theFileNamePart, IRecordHandler theHandler, char theDelimiter, QuoteMode theQuoteMode, boolean theIsPartialFilename) {
iterateOverZipFile(theDescriptors, theFileNamePart, theHandler, theDelimiter, theQuoteMode, theIsPartialFilename, false);
}
private static void iterateOverZipFile(LoadedFileDescriptors theDescriptors, String theFileNamePart, IRecordHandler theHandler, char theDelimiter, QuoteMode theQuoteMode, boolean theIsPartialFilename, boolean theRequireMatch) {
boolean foundMatch = false; boolean foundMatch = false;
for (FileDescriptor nextZipBytes : theDescriptors.getUncompressedFileDescriptors()) { for (FileDescriptor nextZipBytes : theDescriptors.getUncompressedFileDescriptors()) {
@ -644,7 +657,7 @@ public class TermLoaderSvcImpl implements ITermLoaderSvc {
} }
if (!foundMatch) { if (!foundMatch && theRequireMatch) {
throw new InvalidRequestException("Did not find file matching " + theFileNamePart); throw new InvalidRequestException("Did not find file matching " + theFileNamePart);
} }

View File

@ -192,7 +192,7 @@ public abstract class BaseLoincHandler implements IRecordHandler {
if (isNotBlank(theVersionPropertyName)) { if (isNotBlank(theVersionPropertyName)) {
version = myUploadProperties.getProperty(theVersionPropertyName); version = myUploadProperties.getProperty(theVersionPropertyName);
} else { } else {
version = myUploadProperties.getProperty(LOINC_CONCEPTMAP_VERSION.getCode()); version = myUploadProperties.getProperty(LOINC_CODESYSTEM_VERSION.getCode());
} }
ValueSet vs; ValueSet vs;

View File

@ -85,6 +85,9 @@ public class LoincRsnaPlaybookHandler extends BaseLoincHandler implements IRecor
// ConceptMap version from properties files // ConceptMap version from properties files
String loincRsnaCmVersion = myUploadProperties.getProperty(LOINC_CONCEPTMAP_VERSION.getCode()); String loincRsnaCmVersion = myUploadProperties.getProperty(LOINC_CONCEPTMAP_VERSION.getCode());
// CodeSystem version from properties file
String codeSystemVersionId = myUploadProperties.getProperty(LOINC_CODESYSTEM_VERSION.getCode());
// RSNA Codes VS // RSNA Codes VS
ValueSet vs; ValueSet vs;
if (!myIdToValueSet.containsKey(RSNA_CODES_VS_ID)) { if (!myIdToValueSet.containsKey(RSNA_CODES_VS_ID)) {
@ -93,6 +96,7 @@ public class LoincRsnaPlaybookHandler extends BaseLoincHandler implements IRecor
vs.setId(RSNA_CODES_VS_ID); vs.setId(RSNA_CODES_VS_ID);
vs.setName(RSNA_CODES_VS_NAME); vs.setName(RSNA_CODES_VS_NAME);
vs.setStatus(Enumerations.PublicationStatus.ACTIVE); vs.setStatus(Enumerations.PublicationStatus.ACTIVE);
vs.setVersion(codeSystemVersionId);
myIdToValueSet.put(RSNA_CODES_VS_ID, vs); myIdToValueSet.put(RSNA_CODES_VS_ID, vs);
myValueSets.add(vs); myValueSets.add(vs);
} else { } else {
@ -177,7 +181,6 @@ public class LoincRsnaPlaybookHandler extends BaseLoincHandler implements IRecor
String partConceptMapId; String partConceptMapId;
String termConceptMapId; String termConceptMapId;
String codeSystemVersionId = myUploadProperties.getProperty(LOINC_CODESYSTEM_VERSION.getCode());
if (codeSystemVersionId != null) { if (codeSystemVersionId != null) {
partConceptMapId = LoincPartRelatedCodeMappingHandler.LOINC_PART_TO_RID_PART_MAP_ID + "-" + codeSystemVersionId; partConceptMapId = LoincPartRelatedCodeMappingHandler.LOINC_PART_TO_RID_PART_MAP_ID + "-" + codeSystemVersionId;
termConceptMapId = LoincPartRelatedCodeMappingHandler.LOINC_TERM_TO_RPID_PART_MAP_ID + "-" + codeSystemVersionId; termConceptMapId = LoincPartRelatedCodeMappingHandler.LOINC_TERM_TO_RPID_PART_MAP_ID + "-" + codeSystemVersionId;

View File

@ -69,6 +69,8 @@ public enum LoincUploadPropertiesEnum {
LOINC_PART_FILE_DEFAULT("AccessoryFiles/PartFile/Part.csv"), LOINC_PART_FILE_DEFAULT("AccessoryFiles/PartFile/Part.csv"),
// Part link // Part link
LOINC_PART_LINK_FILE("loinc.part.link.file"),
LOINC_PART_LINK_FILE_DEFAULT("AccessoryFiles/PartFile/LoincPartLink.csv"),
LOINC_PART_LINK_FILE_PRIMARY("loinc.part.link.primary.file"), LOINC_PART_LINK_FILE_PRIMARY("loinc.part.link.primary.file"),
LOINC_PART_LINK_FILE_PRIMARY_DEFAULT("AccessoryFiles/PartFile/LoincPartLink_Primary.csv"), LOINC_PART_LINK_FILE_PRIMARY_DEFAULT("AccessoryFiles/PartFile/LoincPartLink_Primary.csv"),
LOINC_PART_LINK_FILE_SUPPLEMENTARY("loinc.part.link.supplementary.file"), LOINC_PART_LINK_FILE_SUPPLEMENTARY("loinc.part.link.supplementary.file"),

View File

@ -39,6 +39,7 @@ import static org.hamcrest.Matchers.contains;
import static org.hamcrest.Matchers.containsString; import static org.hamcrest.Matchers.containsString;
import static org.hamcrest.Matchers.empty; import static org.hamcrest.Matchers.empty;
import static org.junit.jupiter.api.Assertions.assertEquals; import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.junit.jupiter.api.Assertions.assertNull;
import static org.junit.jupiter.api.Assertions.assertTrue; import static org.junit.jupiter.api.Assertions.assertTrue;
import static org.junit.jupiter.api.Assertions.fail; import static org.junit.jupiter.api.Assertions.fail;
import static org.mockito.ArgumentMatchers.any; import static org.mockito.ArgumentMatchers.any;
@ -68,9 +69,54 @@ public class TerminologyLoaderSvcLoincTest extends BaseLoaderTest {
} }
@Test @Test
public void testLoadLoinc() throws Exception { public void testLoadLoincWithSplitPartLink() throws Exception {
addLoincMandatoryFilesToZip(myFiles); addLoincMandatoryFilesToZip(myFiles);
verifyLoadLoinc();
}
@Test
public void testLoadLoincWithSinglePartLink() throws Exception {
addLoincMandatoryFilesAndSinglePartLinkToZip(myFiles);
verifyLoadLoinc();
}
@Test
public void testLoadLoincInvalidPartLinkFiles() throws IOException {
// Missing all PartLinkFiles
addBaseLoincMandatoryFilesToZip(myFiles);
myFiles.addFileZip("/loinc/", LOINC_UPLOAD_PROPERTIES_FILE.getCode());
try {
mySvc.loadLoinc(myFiles.getFiles(), mySrd);
fail();
} catch (UnprocessableEntityException e) {
assertEquals("Could not find any of the PartLink files: [AccessoryFiles/PartFile/LoincPartLink_Primary.csv, AccessoryFiles/PartFile/LoincPartLink_Supplementary.csv] nor [AccessoryFiles/PartFile/LoincPartLink.csv]", e.getMessage());
}
// Missing LoincPartLink_Supplementary
myFiles.addFileZip("/loinc/", LOINC_PART_LINK_FILE_PRIMARY_DEFAULT.getCode());
try {
mySvc.loadLoinc(myFiles.getFiles(), mySrd);
fail();
} catch (UnprocessableEntityException e) {
assertEquals("Could not find any of the PartLink files: [AccessoryFiles/PartFile/LoincPartLink_Supplementary.csv] nor [AccessoryFiles/PartFile/LoincPartLink.csv]", e.getMessage());
}
// Both Split and Single PartLink files
myFiles.addFileZip("/loinc/", LOINC_PART_LINK_FILE_SUPPLEMENTARY_DEFAULT.getCode());
myFiles.addFileZip("/loinc/", LOINC_PART_LINK_FILE_DEFAULT.getCode());
try {
mySvc.loadLoinc(myFiles.getFiles(), mySrd);
fail();
} catch (UnprocessableEntityException e) {
assertEquals("Only either the single PartLink file or the split PartLink files can be present. Found both the single PartLink file, AccessoryFiles/PartFile/LoincPartLink.csv, and the split PartLink files: [AccessoryFiles/PartFile/LoincPartLink_Primary.csv, AccessoryFiles/PartFile/LoincPartLink_Supplementary.csv]", e.getMessage());
}
}
private void verifyLoadLoinc() throws Exception {
// Actually do the load // Actually do the load
mySvc.loadLoinc(myFiles.getFiles(), mySrd); mySvc.loadLoinc(myFiles.getFiles(), mySrd);
@ -138,10 +184,12 @@ public class TerminologyLoaderSvcLoincTest extends BaseLoaderTest {
assertEquals(ITermLoaderSvc.LOINC_URI, vs.getCompose().getInclude().get(0).getSystem()); assertEquals(ITermLoaderSvc.LOINC_URI, vs.getCompose().getInclude().get(0).getSystem());
assertEquals("LA6270-8", vs.getCompose().getInclude().get(0).getConcept().get(0).getCode()); assertEquals("LA6270-8", vs.getCompose().getInclude().get(0).getConcept().get(0).getCode());
assertEquals("Never", vs.getCompose().getInclude().get(0).getConcept().get(0).getDisplay()); assertEquals("Never", vs.getCompose().getInclude().get(0).getConcept().get(0).getDisplay());
assertEquals("Beta.1", vs.getVersion());
// External AnswerList // External AnswerList
vs = valueSets.get("LL1892-0"); vs = valueSets.get("LL1892-0");
assertEquals(0, vs.getCompose().getIncludeFirstRep().getConcept().size()); assertEquals(0, vs.getCompose().getIncludeFirstRep().getConcept().size());
assertEquals("Beta.1", vs.getVersion());
// Part // Part
code = concepts.get("LP101394-7"); code = concepts.get("LP101394-7");
@ -175,6 +223,7 @@ public class TerminologyLoaderSvcLoincTest extends BaseLoaderTest {
assertEquals(3, vs.getCompose().getInclude().get(0).getConcept().size()); assertEquals(3, vs.getCompose().getInclude().get(0).getConcept().size());
assertEquals("11488-4", vs.getCompose().getInclude().get(0).getConcept().get(0).getCode()); assertEquals("11488-4", vs.getCompose().getInclude().get(0).getConcept().get(0).getCode());
assertEquals("Consult note", vs.getCompose().getInclude().get(0).getConcept().get(0).getDisplay()); assertEquals("Consult note", vs.getCompose().getInclude().get(0).getConcept().get(0).getDisplay());
assertNull(vs.getVersion());
// Document ontology parts // Document ontology parts
code = concepts.get("11488-4"); code = concepts.get("11488-4");
@ -192,6 +241,7 @@ public class TerminologyLoaderSvcLoincTest extends BaseLoaderTest {
assertEquals(ITermLoaderSvc.LOINC_URI, vs.getCompose().getInclude().get(0).getSystem()); assertEquals(ITermLoaderSvc.LOINC_URI, vs.getCompose().getInclude().get(0).getSystem());
assertEquals("17787-3", vs.getCompose().getInclude().get(0).getConcept().get(0).getCode()); assertEquals("17787-3", vs.getCompose().getInclude().get(0).getConcept().get(0).getCode());
assertEquals("NM Thyroid gland Study report", vs.getCompose().getInclude().get(0).getConcept().get(0).getDisplay()); assertEquals("NM Thyroid gland Study report", vs.getCompose().getInclude().get(0).getConcept().get(0).getDisplay());
assertNull(vs.getVersion());
// RSNA Playbook Code Parts - Region Imaged // RSNA Playbook Code Parts - Region Imaged
code = concepts.get("17787-3"); code = concepts.get("17787-3");
@ -260,6 +310,7 @@ public class TerminologyLoaderSvcLoincTest extends BaseLoaderTest {
assertEquals("Creatinine [Mass/volume] in Serum or Plasma", vs.getCompose().getInclude().get(0).getConcept().get(0).getDisplay()); assertEquals("Creatinine [Mass/volume] in Serum or Plasma", vs.getCompose().getInclude().get(0).getConcept().get(0).getDisplay());
assertEquals("718-7", vs.getCompose().getInclude().get(0).getConcept().get(1).getCode()); assertEquals("718-7", vs.getCompose().getInclude().get(0).getConcept().get(1).getCode());
assertEquals("Hemoglobin [Mass/volume] in Blood", vs.getCompose().getInclude().get(0).getConcept().get(1).getDisplay()); assertEquals("Hemoglobin [Mass/volume] in Blood", vs.getCompose().getInclude().get(0).getConcept().get(1).getDisplay());
assertNull(vs.getVersion());
// TOP 2000 - SI // TOP 2000 - SI
vs = valueSets.get(LoincTop2000LabResultsSiHandler.TOP_2000_SI_VS_ID); vs = valueSets.get(LoincTop2000LabResultsSiHandler.TOP_2000_SI_VS_ID);
@ -272,6 +323,7 @@ public class TerminologyLoaderSvcLoincTest extends BaseLoaderTest {
assertEquals("Creatinine [Moles/volume] in Serum or Plasma", vs.getCompose().getInclude().get(0).getConcept().get(0).getDisplay()); assertEquals("Creatinine [Moles/volume] in Serum or Plasma", vs.getCompose().getInclude().get(0).getConcept().get(0).getDisplay());
assertEquals("718-7", vs.getCompose().getInclude().get(0).getConcept().get(1).getCode()); assertEquals("718-7", vs.getCompose().getInclude().get(0).getConcept().get(1).getCode());
assertEquals("Hemoglobin [Mass/volume] in Blood", vs.getCompose().getInclude().get(0).getConcept().get(1).getDisplay()); assertEquals("Hemoglobin [Mass/volume] in Blood", vs.getCompose().getInclude().get(0).getConcept().get(1).getDisplay());
assertNull(vs.getVersion());
// Universal lab order VS // Universal lab order VS
vs = valueSets.get(LoincUniversalOrderSetHandler.VS_ID_BASE); vs = valueSets.get(LoincUniversalOrderSetHandler.VS_ID_BASE);
@ -280,6 +332,7 @@ public class TerminologyLoaderSvcLoincTest extends BaseLoaderTest {
assertEquals(9, vs.getCompose().getInclude().get(0).getConcept().size()); assertEquals(9, vs.getCompose().getInclude().get(0).getConcept().size());
assertEquals("42176-8", vs.getCompose().getInclude().get(0).getConcept().get(0).getCode()); assertEquals("42176-8", vs.getCompose().getInclude().get(0).getConcept().get(0).getCode());
assertEquals("1,3 beta glucan [Mass/volume] in Serum", vs.getCompose().getInclude().get(0).getConcept().get(0).getDisplay()); assertEquals("1,3 beta glucan [Mass/volume] in Serum", vs.getCompose().getInclude().get(0).getConcept().get(0).getDisplay());
assertNull(vs.getVersion());
// All LOINC codes // All LOINC codes
assertTrue(valueSets.containsKey("loinc-all")); assertTrue(valueSets.containsKey("loinc-all"));
@ -296,6 +349,7 @@ public class TerminologyLoaderSvcLoincTest extends BaseLoaderTest {
assertTrue(vs.getCompose().hasInclude()); assertTrue(vs.getCompose().hasInclude());
assertEquals(1, vs.getCompose().getInclude().size()); assertEquals(1, vs.getCompose().getInclude().size());
assertEquals(ITermLoaderSvc.LOINC_URI, vs.getCompose().getInclude().get(0).getSystem()); assertEquals(ITermLoaderSvc.LOINC_URI, vs.getCompose().getInclude().get(0).getSystem());
assertEquals("1.0.0", vs.getVersion());
// IEEE Medical Device Codes // IEEE Medical Device Codes
conceptMap = conceptMaps.get(LoincIeeeMedicalDeviceCodeHandler.LOINC_IEEE_CM_ID); conceptMap = conceptMaps.get(LoincIeeeMedicalDeviceCodeHandler.LOINC_IEEE_CM_ID);
@ -353,6 +407,18 @@ public class TerminologyLoaderSvcLoincTest extends BaseLoaderTest {
verify(myTermCodeSystemStorageSvc, times(1)).storeNewCodeSystemVersion(mySystemCaptor.capture(), myCsvCaptor.capture(), any(RequestDetails.class), myValueSetsCaptor.capture(), myConceptMapCaptor.capture()); verify(myTermCodeSystemStorageSvc, times(1)).storeNewCodeSystemVersion(mySystemCaptor.capture(), myCsvCaptor.capture(), any(RequestDetails.class), myValueSetsCaptor.capture(), myConceptMapCaptor.capture());
CodeSystem loincCS = mySystemCaptor.getValue(); CodeSystem loincCS = mySystemCaptor.getValue();
assertEquals("2.67", loincCS.getVersion()); assertEquals("2.67", loincCS.getVersion());
List<ValueSet> loincVS_resources = myValueSetsCaptor.getValue();
for (ValueSet loincVS : loincVS_resources) {
if (loincVS.getId().startsWith("LL1000-0") || loincVS.getId().startsWith("LL1001-8") || loincVS.getId().startsWith("LL1892-0")) {
assertEquals("2.67.Beta.1", loincVS.getVersion());
} else {
assertEquals("2.67", loincVS.getVersion());
}
}
List<ConceptMap> loincCM_resources = myConceptMapCaptor.getValue();
for (ConceptMap loincCM : loincCM_resources) {
assertEquals("2.67.Beta.1", loincCM.getVersion());
}
// Update LOINC marked as version 2.67 // Update LOINC marked as version 2.67
myFiles = new ZipCollectionBuilder(); myFiles = new ZipCollectionBuilder();
@ -362,6 +428,18 @@ public class TerminologyLoaderSvcLoincTest extends BaseLoaderTest {
verify(myTermCodeSystemStorageSvc, times(2)).storeNewCodeSystemVersion(mySystemCaptor.capture(), myCsvCaptor.capture(), any(RequestDetails.class), myValueSetsCaptor.capture(), myConceptMapCaptor.capture()); verify(myTermCodeSystemStorageSvc, times(2)).storeNewCodeSystemVersion(mySystemCaptor.capture(), myCsvCaptor.capture(), any(RequestDetails.class), myValueSetsCaptor.capture(), myConceptMapCaptor.capture());
loincCS = mySystemCaptor.getValue(); loincCS = mySystemCaptor.getValue();
assertEquals("2.67", loincCS.getVersion()); assertEquals("2.67", loincCS.getVersion());
loincVS_resources = myValueSetsCaptor.getValue();
for (ValueSet loincVS : loincVS_resources) {
if (loincVS.getId().startsWith("LL1000-0") || loincVS.getId().startsWith("LL1001-8") || loincVS.getId().startsWith("LL1892-0")) {
assertEquals("2.67.Beta.1", loincVS.getVersion());
} else {
assertEquals("2.67", loincVS.getVersion());
}
}
loincCM_resources = myConceptMapCaptor.getValue();
for (ConceptMap loincCM : loincCM_resources) {
assertEquals("2.67.Beta.1", loincCM.getVersion());
}
// Load LOINC marked as version 2.68 // Load LOINC marked as version 2.68
myFiles = new ZipCollectionBuilder(); myFiles = new ZipCollectionBuilder();
@ -371,6 +449,18 @@ public class TerminologyLoaderSvcLoincTest extends BaseLoaderTest {
verify(myTermCodeSystemStorageSvc, times(3)).storeNewCodeSystemVersion(mySystemCaptor.capture(), myCsvCaptor.capture(), any(RequestDetails.class), myValueSetsCaptor.capture(), myConceptMapCaptor.capture()); verify(myTermCodeSystemStorageSvc, times(3)).storeNewCodeSystemVersion(mySystemCaptor.capture(), myCsvCaptor.capture(), any(RequestDetails.class), myValueSetsCaptor.capture(), myConceptMapCaptor.capture());
loincCS = mySystemCaptor.getValue(); loincCS = mySystemCaptor.getValue();
assertEquals("2.68", loincCS.getVersion()); assertEquals("2.68", loincCS.getVersion());
loincVS_resources = myValueSetsCaptor.getValue();
for (ValueSet loincVS : loincVS_resources) {
if (loincVS.getId().startsWith("LL1000-0") || loincVS.getId().startsWith("LL1001-8") || loincVS.getId().startsWith("LL1892-0")) {
assertEquals("2.68.Beta.1", loincVS.getVersion());
} else {
assertEquals("2.68", loincVS.getVersion());
}
}
loincCM_resources = myConceptMapCaptor.getValue();
for (ConceptMap loincCM : loincCM_resources) {
assertEquals("2.68.Beta.1", loincCM.getVersion());
}
} }
@ -413,12 +503,27 @@ public class TerminologyLoaderSvcLoincTest extends BaseLoaderTest {
} }
} }
public static void addLoincMandatoryFilesAndSinglePartLinkToZip(ZipCollectionBuilder theFiles) throws IOException {
addBaseLoincMandatoryFilesToZip(theFiles);
theFiles.addFileZip("/loinc/", "loincupload_singlepartlink.properties");
theFiles.addFileZip("/loinc/", LOINC_PART_LINK_FILE_DEFAULT.getCode());
}
public static void addLoincMandatoryFilesToZip(ZipCollectionBuilder theFiles) throws IOException { public static void addLoincMandatoryFilesToZip(ZipCollectionBuilder theFiles) throws IOException {
addLoincMandatoryFilesWithPropertiesFileToZip(theFiles, LOINC_UPLOAD_PROPERTIES_FILE.getCode()); addBaseLoincMandatoryFilesToZip(theFiles);
theFiles.addFileZip("/loinc/", LOINC_UPLOAD_PROPERTIES_FILE.getCode());
theFiles.addFileZip("/loinc/", LOINC_PART_LINK_FILE_PRIMARY_DEFAULT.getCode());
theFiles.addFileZip("/loinc/", LOINC_PART_LINK_FILE_SUPPLEMENTARY_DEFAULT.getCode());
} }
public static void addLoincMandatoryFilesWithPropertiesFileToZip(ZipCollectionBuilder theFiles, String thePropertiesFile) throws IOException { public static void addLoincMandatoryFilesWithPropertiesFileToZip(ZipCollectionBuilder theFiles, String thePropertiesFile) throws IOException {
theFiles.addFileZip("/loinc/", thePropertiesFile); theFiles.addFileZip("/loinc/", thePropertiesFile);
theFiles.addFileZip("/loinc/", LOINC_PART_LINK_FILE_PRIMARY_DEFAULT.getCode());
theFiles.addFileZip("/loinc/", LOINC_PART_LINK_FILE_SUPPLEMENTARY_DEFAULT.getCode());
addBaseLoincMandatoryFilesToZip(theFiles);
}
private static void addBaseLoincMandatoryFilesToZip(ZipCollectionBuilder theFiles) throws IOException{
theFiles.addFileZip("/loinc/", LOINC_GROUP_FILE_DEFAULT.getCode()); theFiles.addFileZip("/loinc/", LOINC_GROUP_FILE_DEFAULT.getCode());
theFiles.addFileZip("/loinc/", LOINC_GROUP_TERMS_FILE_DEFAULT.getCode()); theFiles.addFileZip("/loinc/", LOINC_GROUP_TERMS_FILE_DEFAULT.getCode());
theFiles.addFileZip("/loinc/", LOINC_PARENT_GROUP_FILE_DEFAULT.getCode()); theFiles.addFileZip("/loinc/", LOINC_PARENT_GROUP_FILE_DEFAULT.getCode());
@ -430,8 +535,6 @@ public class TerminologyLoaderSvcLoincTest extends BaseLoaderTest {
theFiles.addFileZip("/loinc/", LOINC_ANSWERLIST_LINK_FILE_DEFAULT.getCode()); theFiles.addFileZip("/loinc/", LOINC_ANSWERLIST_LINK_FILE_DEFAULT.getCode());
theFiles.addFileZip("/loinc/", LOINC_ANSWERLIST_LINK_DUPLICATE_FILE_DEFAULT.getCode()); theFiles.addFileZip("/loinc/", LOINC_ANSWERLIST_LINK_DUPLICATE_FILE_DEFAULT.getCode());
theFiles.addFileZip("/loinc/", LOINC_PART_FILE_DEFAULT.getCode()); theFiles.addFileZip("/loinc/", LOINC_PART_FILE_DEFAULT.getCode());
theFiles.addFileZip("/loinc/", LOINC_PART_LINK_FILE_PRIMARY_DEFAULT.getCode());
theFiles.addFileZip("/loinc/", LOINC_PART_LINK_FILE_SUPPLEMENTARY_DEFAULT.getCode());
theFiles.addFileZip("/loinc/", LOINC_PART_RELATED_CODE_MAPPING_FILE_DEFAULT.getCode()); theFiles.addFileZip("/loinc/", LOINC_PART_RELATED_CODE_MAPPING_FILE_DEFAULT.getCode());
theFiles.addFileZip("/loinc/", LOINC_DOCUMENT_ONTOLOGY_FILE_DEFAULT.getCode()); theFiles.addFileZip("/loinc/", LOINC_DOCUMENT_ONTOLOGY_FILE_DEFAULT.getCode());
theFiles.addFileZip("/loinc/", LOINC_RSNA_PLAYBOOK_FILE_DEFAULT.getCode()); theFiles.addFileZip("/loinc/", LOINC_RSNA_PLAYBOOK_FILE_DEFAULT.getCode());

View File

@ -0,0 +1,10 @@
"LoincNumber","LongCommonName","PartNumber","PartName","PartCodeSystem","PartTypeName","LinkTypeName","Property"
"10013-1","R' wave amplitude in lead I","LP31101-6","R' wave amplitude.lead I","http://loinc.org","COMPONENT","Primary","http://loinc.org/property/COMPONENT"
"10013-1","R' wave amplitude in lead I","LP6802-5","Elpot","http://loinc.org","PROPERTY","Primary","http://loinc.org/property/PROPERTY"
"10013-1","R' wave amplitude in lead I","LP6960-1","Pt","http://loinc.org","TIME","Primary","http://loinc.org/property/TIME_ASPCT"
"10013-1","R' wave amplitude in lead I","LP7289-4","Heart","http://loinc.org","SYSTEM","Primary","http://loinc.org/property/SYSTEM"
"10013-1","R' wave amplitude in lead I","LP7753-9","Qn","http://loinc.org","SCALE","Primary","http://loinc.org/property/SCALE_TYP"
"10013-1","R' wave amplitude in lead I","LP6244-0","EKG","http://loinc.org","METHOD","Primary","http://loinc.org/property/METHOD_TYP"
"10013-1","R' wave amplitude in lead I","LP31101-6","R' wave amplitude.lead I","http://loinc.org","COMPONENT","DetailedModel","http://loinc.org/property/analyte"
"10013-1","R' wave amplitude in lead I","LP6802-5","Elpot","http://loinc.org","PROPERTY","DetailedModel","http://loinc.org/property/PROPERTY"
"10013-1","R' wave amplitude in lead I","LP6960-1","Pt","http://loinc.org","TIME","DetailedModel","http://loinc.org/property/time-core"
1 LoincNumber LongCommonName PartNumber PartName PartCodeSystem PartTypeName LinkTypeName Property
2 10013-1 R' wave amplitude in lead I LP31101-6 R' wave amplitude.lead I http://loinc.org COMPONENT Primary http://loinc.org/property/COMPONENT
3 10013-1 R' wave amplitude in lead I LP6802-5 Elpot http://loinc.org PROPERTY Primary http://loinc.org/property/PROPERTY
4 10013-1 R' wave amplitude in lead I LP6960-1 Pt http://loinc.org TIME Primary http://loinc.org/property/TIME_ASPCT
5 10013-1 R' wave amplitude in lead I LP7289-4 Heart http://loinc.org SYSTEM Primary http://loinc.org/property/SYSTEM
6 10013-1 R' wave amplitude in lead I LP7753-9 Qn http://loinc.org SCALE Primary http://loinc.org/property/SCALE_TYP
7 10013-1 R' wave amplitude in lead I LP6244-0 EKG http://loinc.org METHOD Primary http://loinc.org/property/METHOD_TYP
8 10013-1 R' wave amplitude in lead I LP31101-6 R' wave amplitude.lead I http://loinc.org COMPONENT DetailedModel http://loinc.org/property/analyte
9 10013-1 R' wave amplitude in lead I LP6802-5 Elpot http://loinc.org PROPERTY DetailedModel http://loinc.org/property/PROPERTY
10 10013-1 R' wave amplitude in lead I LP6960-1 Pt http://loinc.org TIME DetailedModel http://loinc.org/property/time-core

View File

@ -0,0 +1,82 @@
#################
### MANDATORY ###
#################
# Answer lists (ValueSets of potential answers/values for LOINC "questions")
## File must be present
loinc.answerlist.file=AccessoryFiles/AnswerFile/AnswerList.csv
# Answer list links (connects LOINC observation codes to answer list codes)
## File must be present
loinc.answerlist.link.file=AccessoryFiles/AnswerFile/LoincAnswerListLink.csv
# Document ontology
## File must be present
loinc.document.ontology.file=AccessoryFiles/DocumentOntology/DocumentOntology.csv
# LOINC codes
## File must be present
loinc.file=LoincTable/Loinc.csv
# LOINC hierarchy
## File must be present
loinc.hierarchy.file=AccessoryFiles/MultiAxialHierarchy/MultiAxialHierarchy.csv
# IEEE medical device codes
## File must be present
loinc.ieee.medical.device.code.mapping.table.file=AccessoryFiles/LoincIeeeMedicalDeviceCodeMappingTable/LoincIeeeMedicalDeviceCodeMappingTable.csv
# Imaging document codes
## File must be present
loinc.imaging.document.codes.file=AccessoryFiles/ImagingDocuments/ImagingDocumentCodes.csv
# Part
## File must be present
loinc.part.file=AccessoryFiles/PartFile/Part.csv
# Part link
## File must be present
loinc.part.link.file=AccessoryFiles/PartFile/LoincPartLink.csv
# Part related code mapping
## File must be present
loinc.part.related.code.mapping.file=AccessoryFiles/PartFile/PartRelatedCodeMapping.csv
# RSNA playbook
## File must be present
loinc.rsna.playbook.file=AccessoryFiles/LoincRsnaRadiologyPlaybook/LoincRsnaRadiologyPlaybook.csv
# Top 2000 codes - SI
## File must be present
loinc.top2000.common.lab.results.si.file=AccessoryFiles/Top2000Results/SI/Top2000CommonLabResultsSi.csv
# Top 2000 codes - US
## File must be present
loinc.top2000.common.lab.results.us.file=AccessoryFiles/Top2000Results/US/Top2000CommonLabResultsUs.csv
# Universal lab order ValueSet
## File must be present
loinc.universal.lab.order.valueset.file=AccessoryFiles/LoincUniversalLabOrdersValueSet/LoincUniversalLabOrdersValueSet.csv
################
### OPTIONAL ###
################
# This is the version identifier for the answer list file
## Key may be omitted
loinc.answerlist.version=Beta.1
# This is the version identifier for uploaded ConceptMap resources
## Key may be omitted
loinc.conceptmap.version=Beta.1
# Group
## Default value if key not provided: AccessoryFiles/GroupFile/Group.csv
## File may be omitted
loinc.group.file=AccessoryFiles/GroupFile/Group.csv
# Group terms
## Default value if key not provided: AccessoryFiles/GroupFile/GroupLoincTerms.csv
## File may be omitted
loinc.group.terms.file=AccessoryFiles/GroupFile/GroupLoincTerms.csv
# Parent group
## Default value if key not provided: AccessoryFiles/GroupFile/ParentGroup.csv
## File may be omitted
loinc.parent.group.file=AccessoryFiles/GroupFile/ParentGroup.csv

View File

@ -67,11 +67,11 @@ loinc.codesystem.version=2.67
# This is the version identifier for the answer list file # This is the version identifier for the answer list file
## Key may be omitted ## Key may be omitted
loinc.answerlist.version=Beta.1 loinc.answerlist.version=2.67.Beta.1
# This is the version identifier for uploaded ConceptMap resources # This is the version identifier for uploaded ConceptMap resources
## Key may be omitted ## Key may be omitted
loinc.conceptmap.version=Beta.1 loinc.conceptmap.version=2.67.Beta.1
# Group # Group
## Default value if key not provided: AccessoryFiles/GroupFile/Group.csv ## Default value if key not provided: AccessoryFiles/GroupFile/Group.csv

View File

@ -67,11 +67,11 @@ loinc.codesystem.version=2.68
# This is the version identifier for the answer list file # This is the version identifier for the answer list file
## Key may be omitted ## Key may be omitted
loinc.answerlist.version=Beta.1 loinc.answerlist.version=2.68.Beta.1
# This is the version identifier for uploaded ConceptMap resources # This is the version identifier for uploaded ConceptMap resources
## Key may be omitted ## Key may be omitted
loinc.conceptmap.version=Beta.1 loinc.conceptmap.version=2.68.Beta.1
# Group # Group
## Default value if key not provided: AccessoryFiles/GroupFile/Group.csv ## Default value if key not provided: AccessoryFiles/GroupFile/Group.csv