Merge remote-tracking branch 'origin/master' into 2849_add_new_mdm_param
This commit is contained in:
commit
2bc024fef9
|
@ -0,0 +1,5 @@
|
||||||
|
---
|
||||||
|
type: add
|
||||||
|
issue: 2786
|
||||||
|
title: "Add 'loinc.codesystem.make.current' property to upload-terminology command to allow loading LOINC version
|
||||||
|
without becoming current."
|
|
@ -27,14 +27,14 @@ import ca.uhn.fhir.context.support.ValidationSupportContext;
|
||||||
import ca.uhn.fhir.jpa.api.dao.IFhirResourceDaoCodeSystem;
|
import ca.uhn.fhir.jpa.api.dao.IFhirResourceDaoCodeSystem;
|
||||||
import ca.uhn.fhir.jpa.dao.BaseHapiFhirResourceDao;
|
import ca.uhn.fhir.jpa.dao.BaseHapiFhirResourceDao;
|
||||||
import ca.uhn.fhir.jpa.model.cross.IBasePersistedResource;
|
import ca.uhn.fhir.jpa.model.cross.IBasePersistedResource;
|
||||||
import ca.uhn.fhir.jpa.term.api.ITermDeferredStorageSvc;
|
|
||||||
import ca.uhn.fhir.rest.api.server.storage.ResourcePersistentId;
|
|
||||||
import ca.uhn.fhir.jpa.model.entity.ResourceTable;
|
import ca.uhn.fhir.jpa.model.entity.ResourceTable;
|
||||||
import ca.uhn.fhir.rest.api.server.storage.TransactionDetails;
|
|
||||||
import ca.uhn.fhir.jpa.searchparam.SearchParameterMap;
|
import ca.uhn.fhir.jpa.searchparam.SearchParameterMap;
|
||||||
import ca.uhn.fhir.jpa.term.api.ITermCodeSystemStorageSvc;
|
import ca.uhn.fhir.jpa.term.api.ITermCodeSystemStorageSvc;
|
||||||
|
import ca.uhn.fhir.jpa.term.api.ITermDeferredStorageSvc;
|
||||||
import ca.uhn.fhir.jpa.util.LogicUtil;
|
import ca.uhn.fhir.jpa.util.LogicUtil;
|
||||||
import ca.uhn.fhir.rest.api.server.RequestDetails;
|
import ca.uhn.fhir.rest.api.server.RequestDetails;
|
||||||
|
import ca.uhn.fhir.rest.api.server.storage.ResourcePersistentId;
|
||||||
|
import ca.uhn.fhir.rest.api.server.storage.TransactionDetails;
|
||||||
import ca.uhn.fhir.rest.param.TokenParam;
|
import ca.uhn.fhir.rest.param.TokenParam;
|
||||||
import ca.uhn.fhir.rest.server.exceptions.InvalidRequestException;
|
import ca.uhn.fhir.rest.server.exceptions.InvalidRequestException;
|
||||||
import org.hl7.fhir.instance.model.api.IBaseResource;
|
import org.hl7.fhir.instance.model.api.IBaseResource;
|
||||||
|
@ -52,7 +52,6 @@ import java.util.List;
|
||||||
import java.util.Set;
|
import java.util.Set;
|
||||||
|
|
||||||
import static ca.uhn.fhir.jpa.dao.FhirResourceDaoValueSetDstu2.toStringOrNull;
|
import static ca.uhn.fhir.jpa.dao.FhirResourceDaoValueSetDstu2.toStringOrNull;
|
||||||
import static ca.uhn.fhir.jpa.dao.dstu3.FhirResourceDaoValueSetDstu3.vsValidateCodeOptions;
|
|
||||||
import static org.apache.commons.lang3.StringUtils.isNotBlank;
|
import static org.apache.commons.lang3.StringUtils.isNotBlank;
|
||||||
|
|
||||||
public class FhirResourceDaoCodeSystemR4 extends BaseHapiFhirResourceDao<CodeSystem> implements IFhirResourceDaoCodeSystem<CodeSystem, Coding, CodeableConcept> {
|
public class FhirResourceDaoCodeSystemR4 extends BaseHapiFhirResourceDao<CodeSystem> implements IFhirResourceDaoCodeSystem<CodeSystem, Coding, CodeableConcept> {
|
||||||
|
@ -147,7 +146,7 @@ public class FhirResourceDaoCodeSystemR4 extends BaseHapiFhirResourceDao<CodeSys
|
||||||
CodeSystem cs = (CodeSystem) theResource;
|
CodeSystem cs = (CodeSystem) theResource;
|
||||||
addPidToResource(theEntity, theResource);
|
addPidToResource(theEntity, theResource);
|
||||||
|
|
||||||
myTerminologyCodeSystemStorageSvc.storeNewCodeSystemVersionIfNeeded(cs, (ResourceTable) theEntity);
|
myTerminologyCodeSystemStorageSvc.storeNewCodeSystemVersionIfNeeded(cs, (ResourceTable) theEntity, theRequest);
|
||||||
}
|
}
|
||||||
|
|
||||||
return retVal;
|
return retVal;
|
||||||
|
|
|
@ -86,9 +86,6 @@ import java.util.UUID;
|
||||||
import java.util.concurrent.atomic.AtomicInteger;
|
import java.util.concurrent.atomic.AtomicInteger;
|
||||||
import java.util.stream.Collectors;
|
import java.util.stream.Collectors;
|
||||||
|
|
||||||
import static org.apache.commons.lang3.StringUtils.defaultIfBlank;
|
|
||||||
import static org.apache.commons.lang3.StringUtils.defaultString;
|
|
||||||
import static org.apache.commons.lang3.StringUtils.isBlank;
|
|
||||||
import static org.apache.commons.lang3.StringUtils.isNotBlank;
|
import static org.apache.commons.lang3.StringUtils.isNotBlank;
|
||||||
|
|
||||||
public class TermCodeSystemStorageSvcImpl implements ITermCodeSystemStorageSvc {
|
public class TermCodeSystemStorageSvcImpl implements ITermCodeSystemStorageSvc {
|
||||||
|
@ -342,7 +339,7 @@ public class TermCodeSystemStorageSvcImpl implements ITermCodeSystemStorageSvc {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@Transactional(propagation = Propagation.MANDATORY)
|
@Transactional(propagation = Propagation.MANDATORY)
|
||||||
public void storeNewCodeSystemVersionIfNeeded(CodeSystem theCodeSystem, ResourceTable theResourceEntity) {
|
public void storeNewCodeSystemVersionIfNeeded(CodeSystem theCodeSystem, ResourceTable theResourceEntity, RequestDetails theRequestDetails) {
|
||||||
if (theCodeSystem != null && isNotBlank(theCodeSystem.getUrl())) {
|
if (theCodeSystem != null && isNotBlank(theCodeSystem.getUrl())) {
|
||||||
String codeSystemUrl = theCodeSystem.getUrl();
|
String codeSystemUrl = theCodeSystem.getUrl();
|
||||||
if (theCodeSystem.getContent() == CodeSystem.CodeSystemContentMode.COMPLETE || theCodeSystem.getContent() == null || theCodeSystem.getContent() == CodeSystem.CodeSystemContentMode.NOTPRESENT) {
|
if (theCodeSystem.getContent() == CodeSystem.CodeSystemContentMode.COMPLETE || theCodeSystem.getContent() == null || theCodeSystem.getContent() == CodeSystem.CodeSystemContentMode.NOTPRESENT) {
|
||||||
|
@ -373,7 +370,8 @@ public class TermCodeSystemStorageSvcImpl implements ITermCodeSystemStorageSvc {
|
||||||
|
|
||||||
persCs.getConcepts().addAll(BaseTermReadSvcImpl.toPersistedConcepts(theCodeSystem.getConcept(), persCs));
|
persCs.getConcepts().addAll(BaseTermReadSvcImpl.toPersistedConcepts(theCodeSystem.getConcept(), persCs));
|
||||||
ourLog.debug("Code system has {} concepts", persCs.getConcepts().size());
|
ourLog.debug("Code system has {} concepts", persCs.getConcepts().size());
|
||||||
storeNewCodeSystemVersion(codeSystemResourcePid, codeSystemUrl, theCodeSystem.getName(), theCodeSystem.getVersion(), persCs, theResourceEntity);
|
storeNewCodeSystemVersion(codeSystemResourcePid, codeSystemUrl, theCodeSystem.getName(),
|
||||||
|
theCodeSystem.getVersion(), persCs, theResourceEntity, theRequestDetails);
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -381,13 +379,14 @@ public class TermCodeSystemStorageSvcImpl implements ITermCodeSystemStorageSvc {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@Transactional
|
@Transactional
|
||||||
public IIdType storeNewCodeSystemVersion(CodeSystem theCodeSystemResource, TermCodeSystemVersion theCodeSystemVersion, RequestDetails theRequest, List<ValueSet> theValueSets, List<ConceptMap> theConceptMaps) {
|
public IIdType storeNewCodeSystemVersion(CodeSystem theCodeSystemResource, TermCodeSystemVersion theCodeSystemVersion,
|
||||||
|
RequestDetails theRequest, List<ValueSet> theValueSets, List<ConceptMap> theConceptMaps) {
|
||||||
assert TransactionSynchronizationManager.isActualTransactionActive();
|
assert TransactionSynchronizationManager.isActualTransactionActive();
|
||||||
|
|
||||||
Validate.notBlank(theCodeSystemResource.getUrl(), "theCodeSystemResource must have a URL");
|
Validate.notBlank(theCodeSystemResource.getUrl(), "theCodeSystemResource must have a URL");
|
||||||
|
|
||||||
// Note that this creates the TermCodeSystem and TermCodeSystemVersion entities if needed
|
// Note that this creates the TermCodeSystem and TermCodeSystemVersion entities if needed
|
||||||
IIdType csId = myTerminologyVersionAdapterSvc.createOrUpdateCodeSystem(theCodeSystemResource);
|
IIdType csId = myTerminologyVersionAdapterSvc.createOrUpdateCodeSystem(theCodeSystemResource, theRequest);
|
||||||
|
|
||||||
ResourcePersistentId codeSystemResourcePid = myIdHelperService.resolveResourcePersistentIds(RequestPartitionId.allPartitions(), csId.getResourceType(), csId.getIdPart());
|
ResourcePersistentId codeSystemResourcePid = myIdHelperService.resolveResourcePersistentIds(RequestPartitionId.allPartitions(), csId.getResourceType(), csId.getIdPart());
|
||||||
ResourceTable resource = myResourceTableDao.getOne(codeSystemResourcePid.getIdAsLong());
|
ResourceTable resource = myResourceTableDao.getOne(codeSystemResourcePid.getIdAsLong());
|
||||||
|
@ -396,7 +395,8 @@ public class TermCodeSystemStorageSvcImpl implements ITermCodeSystemStorageSvc {
|
||||||
|
|
||||||
populateCodeSystemVersionProperties(theCodeSystemVersion, theCodeSystemResource, resource);
|
populateCodeSystemVersionProperties(theCodeSystemVersion, theCodeSystemResource, resource);
|
||||||
|
|
||||||
storeNewCodeSystemVersion(codeSystemResourcePid, theCodeSystemResource.getUrl(), theCodeSystemResource.getName(), theCodeSystemResource.getVersion(), theCodeSystemVersion, resource);
|
storeNewCodeSystemVersion(codeSystemResourcePid, theCodeSystemResource.getUrl(), theCodeSystemResource.getName(),
|
||||||
|
theCodeSystemResource.getVersion(), theCodeSystemVersion, resource, theRequest);
|
||||||
|
|
||||||
myDeferredStorageSvc.addConceptMapsToStorageQueue(theConceptMaps);
|
myDeferredStorageSvc.addConceptMapsToStorageQueue(theConceptMaps);
|
||||||
myDeferredStorageSvc.addValueSetsToStorageQueue(theValueSets);
|
myDeferredStorageSvc.addValueSetsToStorageQueue(theValueSets);
|
||||||
|
@ -406,7 +406,9 @@ public class TermCodeSystemStorageSvcImpl implements ITermCodeSystemStorageSvc {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@Transactional
|
@Transactional
|
||||||
public void storeNewCodeSystemVersion(ResourcePersistentId theCodeSystemResourcePid, String theSystemUri, String theSystemName, String theCodeSystemVersionId, TermCodeSystemVersion theCodeSystemVersion, ResourceTable theCodeSystemResourceTable) {
|
public void storeNewCodeSystemVersion(ResourcePersistentId theCodeSystemResourcePid, String theSystemUri,
|
||||||
|
String theSystemName, String theCodeSystemVersionId, TermCodeSystemVersion theCodeSystemVersion,
|
||||||
|
ResourceTable theCodeSystemResourceTable, RequestDetails theRequestDetails) {
|
||||||
assert TransactionSynchronizationManager.isActualTransactionActive();
|
assert TransactionSynchronizationManager.isActualTransactionActive();
|
||||||
|
|
||||||
ourLog.debug("Storing code system");
|
ourLog.debug("Storing code system");
|
||||||
|
@ -468,34 +470,42 @@ public class TermCodeSystemStorageSvcImpl implements ITermCodeSystemStorageSvc {
|
||||||
codeSystemToStore = myCodeSystemVersionDao.saveAndFlush(codeSystemToStore);
|
codeSystemToStore = myCodeSystemVersionDao.saveAndFlush(codeSystemToStore);
|
||||||
}
|
}
|
||||||
|
|
||||||
ourLog.debug("Saving code system");
|
// defaults to true
|
||||||
|
boolean isMakeVersionCurrent = theRequestDetails == null ||
|
||||||
codeSystem.setCurrentVersion(codeSystemToStore);
|
(boolean) theRequestDetails.getUserData().getOrDefault(MAKE_LOADING_VERSION_CURRENT, Boolean.TRUE);
|
||||||
if (codeSystem.getPid() == null) {
|
if (isMakeVersionCurrent) {
|
||||||
codeSystem = myCodeSystemDao.saveAndFlush(codeSystem);
|
makeCodeSystemCurrentVersion(codeSystem, codeSystemToStore, conceptsToSave, totalCodeCount);
|
||||||
}
|
}
|
||||||
|
|
||||||
ourLog.debug("Setting CodeSystemVersion[{}] on {} concepts...", codeSystem.getPid(), totalCodeCount);
|
|
||||||
|
|
||||||
for (TermConcept next : conceptsToSave) {
|
|
||||||
populateVersion(next, codeSystemToStore);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
ourLog.debug("Saving {} concepts...", totalCodeCount);
|
|
||||||
|
|
||||||
|
private void makeCodeSystemCurrentVersion(TermCodeSystem theCodeSystem, TermCodeSystemVersion theCodeSystemToStore,
|
||||||
|
Collection<TermConcept> theConceptsToSave, int theTotalCodeCount) {
|
||||||
|
|
||||||
|
theCodeSystem.setCurrentVersion(theCodeSystemToStore);
|
||||||
|
if (theCodeSystem.getPid() == null) {
|
||||||
|
theCodeSystem = myCodeSystemDao.saveAndFlush(theCodeSystem);
|
||||||
|
}
|
||||||
|
|
||||||
|
ourLog.debug("Setting CodeSystemVersion[{}] on {} concepts...", theCodeSystem.getPid(), theTotalCodeCount);
|
||||||
|
for (TermConcept next : theConceptsToSave) {
|
||||||
|
populateVersion(next, theCodeSystemToStore);
|
||||||
|
}
|
||||||
|
|
||||||
|
ourLog.debug("Saving {} concepts...", theTotalCodeCount);
|
||||||
IdentityHashMap<TermConcept, Object> conceptsStack2 = new IdentityHashMap<>();
|
IdentityHashMap<TermConcept, Object> conceptsStack2 = new IdentityHashMap<>();
|
||||||
for (TermConcept next : conceptsToSave) {
|
for (TermConcept next : theConceptsToSave) {
|
||||||
persistChildren(next, codeSystemToStore, conceptsStack2, totalCodeCount);
|
persistChildren(next, theCodeSystemToStore, conceptsStack2, theTotalCodeCount);
|
||||||
}
|
}
|
||||||
|
|
||||||
ourLog.debug("Done saving concepts, flushing to database");
|
ourLog.debug("Done saving concepts, flushing to database");
|
||||||
|
if (! myDeferredStorageSvc.isStorageQueueEmpty()) {
|
||||||
if (myDeferredStorageSvc.isStorageQueueEmpty() == false) {
|
|
||||||
ourLog.info("Note that some concept saving has been deferred");
|
ourLog.info("Note that some concept saving has been deferred");
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
private TermCodeSystemVersion getExistingTermCodeSystemVersion(Long theCodeSystemVersionPid, String theCodeSystemVersion) {
|
private TermCodeSystemVersion getExistingTermCodeSystemVersion(Long theCodeSystemVersionPid, String theCodeSystemVersion) {
|
||||||
TermCodeSystemVersion existing;
|
TermCodeSystemVersion existing;
|
||||||
if (theCodeSystemVersion == null) {
|
if (theCodeSystemVersion == null) {
|
||||||
|
|
|
@ -1,9 +1,95 @@
|
||||||
package ca.uhn.fhir.jpa.term;
|
package ca.uhn.fhir.jpa.term;
|
||||||
|
|
||||||
|
import ca.uhn.fhir.context.FhirContext;
|
||||||
|
import ca.uhn.fhir.jpa.entity.TermCodeSystemVersion;
|
||||||
|
import ca.uhn.fhir.jpa.entity.TermConcept;
|
||||||
|
import ca.uhn.fhir.jpa.entity.TermConceptParentChildLink;
|
||||||
|
import ca.uhn.fhir.jpa.entity.TermConceptProperty;
|
||||||
|
import ca.uhn.fhir.jpa.term.api.ITermCodeSystemStorageSvc;
|
||||||
|
import ca.uhn.fhir.jpa.term.api.ITermDeferredStorageSvc;
|
||||||
|
import ca.uhn.fhir.jpa.term.api.ITermLoaderSvc;
|
||||||
|
import ca.uhn.fhir.jpa.term.custom.CustomTerminologySet;
|
||||||
|
import ca.uhn.fhir.jpa.term.icd10cm.Icd10CmLoader;
|
||||||
|
import ca.uhn.fhir.jpa.term.loinc.LoincAnswerListHandler;
|
||||||
|
import ca.uhn.fhir.jpa.term.loinc.LoincAnswerListLinkHandler;
|
||||||
|
import ca.uhn.fhir.jpa.term.loinc.LoincConsumerNameHandler;
|
||||||
|
import ca.uhn.fhir.jpa.term.loinc.LoincDocumentOntologyHandler;
|
||||||
|
import ca.uhn.fhir.jpa.term.loinc.LoincGroupFileHandler;
|
||||||
|
import ca.uhn.fhir.jpa.term.loinc.LoincGroupTermsFileHandler;
|
||||||
|
import ca.uhn.fhir.jpa.term.loinc.LoincHandler;
|
||||||
|
import ca.uhn.fhir.jpa.term.loinc.LoincHierarchyHandler;
|
||||||
|
import ca.uhn.fhir.jpa.term.loinc.LoincIeeeMedicalDeviceCodeHandler;
|
||||||
|
import ca.uhn.fhir.jpa.term.loinc.LoincImagingDocumentCodeHandler;
|
||||||
|
import ca.uhn.fhir.jpa.term.loinc.LoincLinguisticVariantHandler;
|
||||||
|
import ca.uhn.fhir.jpa.term.loinc.LoincLinguisticVariantsHandler;
|
||||||
|
import ca.uhn.fhir.jpa.term.loinc.LoincParentGroupFileHandler;
|
||||||
|
import ca.uhn.fhir.jpa.term.loinc.LoincPartHandler;
|
||||||
|
import ca.uhn.fhir.jpa.term.loinc.LoincPartLinkHandler;
|
||||||
|
import ca.uhn.fhir.jpa.term.loinc.LoincPartRelatedCodeMappingHandler;
|
||||||
|
import ca.uhn.fhir.jpa.term.loinc.LoincRsnaPlaybookHandler;
|
||||||
|
import ca.uhn.fhir.jpa.term.loinc.LoincTop2000LabResultsSiHandler;
|
||||||
|
import ca.uhn.fhir.jpa.term.loinc.LoincTop2000LabResultsUsHandler;
|
||||||
|
import ca.uhn.fhir.jpa.term.loinc.LoincUniversalOrderSetHandler;
|
||||||
|
import ca.uhn.fhir.jpa.term.loinc.LoincXmlFileZipContentsHandler;
|
||||||
|
import ca.uhn.fhir.jpa.term.loinc.PartTypeAndPartName;
|
||||||
|
import ca.uhn.fhir.jpa.term.snomedct.SctHandlerConcept;
|
||||||
|
import ca.uhn.fhir.jpa.term.snomedct.SctHandlerDescription;
|
||||||
|
import ca.uhn.fhir.jpa.term.snomedct.SctHandlerRelationship;
|
||||||
|
import ca.uhn.fhir.jpa.util.Counter;
|
||||||
|
import ca.uhn.fhir.rest.api.EncodingEnum;
|
||||||
|
import ca.uhn.fhir.rest.api.server.RequestDetails;
|
||||||
|
import ca.uhn.fhir.rest.server.exceptions.InternalErrorException;
|
||||||
|
import ca.uhn.fhir.rest.server.exceptions.InvalidRequestException;
|
||||||
|
import ca.uhn.fhir.util.ClasspathUtil;
|
||||||
|
import ca.uhn.fhir.util.ValidateUtil;
|
||||||
|
import com.google.common.annotations.VisibleForTesting;
|
||||||
|
import com.google.common.base.Charsets;
|
||||||
|
import org.apache.commons.csv.CSVFormat;
|
||||||
|
import org.apache.commons.csv.CSVParser;
|
||||||
|
import org.apache.commons.csv.CSVRecord;
|
||||||
|
import org.apache.commons.csv.QuoteMode;
|
||||||
|
import org.apache.commons.io.IOUtils;
|
||||||
|
import org.apache.commons.lang3.ObjectUtils;
|
||||||
|
import org.apache.commons.lang3.StringUtils;
|
||||||
|
import org.apache.commons.lang3.Validate;
|
||||||
|
import org.hl7.fhir.instance.model.api.IIdType;
|
||||||
|
import org.hl7.fhir.r4.model.CodeSystem;
|
||||||
|
import org.hl7.fhir.r4.model.ConceptMap;
|
||||||
|
import org.hl7.fhir.r4.model.Enumerations;
|
||||||
|
import org.hl7.fhir.r4.model.ValueSet;
|
||||||
|
import org.springframework.aop.support.AopUtils;
|
||||||
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
|
import org.xml.sax.SAXException;
|
||||||
|
|
||||||
|
import javax.annotation.Nonnull;
|
||||||
|
import javax.validation.constraints.NotNull;
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.io.InputStream;
|
||||||
|
import java.io.InputStreamReader;
|
||||||
|
import java.io.LineNumberReader;
|
||||||
|
import java.io.Reader;
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.Arrays;
|
||||||
|
import java.util.Collections;
|
||||||
|
import java.util.Date;
|
||||||
|
import java.util.HashMap;
|
||||||
|
import java.util.HashSet;
|
||||||
|
import java.util.Iterator;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.Locale;
|
||||||
|
import java.util.Map;
|
||||||
|
import java.util.Map.Entry;
|
||||||
|
import java.util.Optional;
|
||||||
|
import java.util.Properties;
|
||||||
|
import java.util.Set;
|
||||||
|
import java.util.stream.Collectors;
|
||||||
|
|
||||||
|
import static ca.uhn.fhir.jpa.term.api.ITermCodeSystemStorageSvc.MAKE_LOADING_VERSION_CURRENT;
|
||||||
import static ca.uhn.fhir.jpa.term.loinc.LoincUploadPropertiesEnum.LOINC_ANSWERLIST_FILE;
|
import static ca.uhn.fhir.jpa.term.loinc.LoincUploadPropertiesEnum.LOINC_ANSWERLIST_FILE;
|
||||||
import static ca.uhn.fhir.jpa.term.loinc.LoincUploadPropertiesEnum.LOINC_ANSWERLIST_FILE_DEFAULT;
|
import static ca.uhn.fhir.jpa.term.loinc.LoincUploadPropertiesEnum.LOINC_ANSWERLIST_FILE_DEFAULT;
|
||||||
import static ca.uhn.fhir.jpa.term.loinc.LoincUploadPropertiesEnum.LOINC_ANSWERLIST_LINK_FILE;
|
import static ca.uhn.fhir.jpa.term.loinc.LoincUploadPropertiesEnum.LOINC_ANSWERLIST_LINK_FILE;
|
||||||
import static ca.uhn.fhir.jpa.term.loinc.LoincUploadPropertiesEnum.LOINC_ANSWERLIST_LINK_FILE_DEFAULT;
|
import static ca.uhn.fhir.jpa.term.loinc.LoincUploadPropertiesEnum.LOINC_ANSWERLIST_LINK_FILE_DEFAULT;
|
||||||
|
import static ca.uhn.fhir.jpa.term.loinc.LoincUploadPropertiesEnum.LOINC_CODESYSTEM_MAKE_CURRENT;
|
||||||
import static ca.uhn.fhir.jpa.term.loinc.LoincUploadPropertiesEnum.LOINC_CODESYSTEM_VERSION;
|
import static ca.uhn.fhir.jpa.term.loinc.LoincUploadPropertiesEnum.LOINC_CODESYSTEM_VERSION;
|
||||||
import static ca.uhn.fhir.jpa.term.loinc.LoincUploadPropertiesEnum.LOINC_CONSUMER_NAME_FILE;
|
import static ca.uhn.fhir.jpa.term.loinc.LoincUploadPropertiesEnum.LOINC_CONSUMER_NAME_FILE;
|
||||||
import static ca.uhn.fhir.jpa.term.loinc.LoincUploadPropertiesEnum.LOINC_CONSUMER_NAME_FILE_DEFAULT;
|
import static ca.uhn.fhir.jpa.term.loinc.LoincUploadPropertiesEnum.LOINC_CONSUMER_NAME_FILE_DEFAULT;
|
||||||
|
@ -49,93 +135,6 @@ import static ca.uhn.fhir.jpa.term.loinc.LoincUploadPropertiesEnum.LOINC_UPLOAD_
|
||||||
import static org.apache.commons.lang3.StringUtils.isBlank;
|
import static org.apache.commons.lang3.StringUtils.isBlank;
|
||||||
import static org.apache.commons.lang3.StringUtils.isNotBlank;
|
import static org.apache.commons.lang3.StringUtils.isNotBlank;
|
||||||
|
|
||||||
import java.io.IOException;
|
|
||||||
import java.io.InputStream;
|
|
||||||
import java.io.InputStreamReader;
|
|
||||||
import java.io.LineNumberReader;
|
|
||||||
import java.io.Reader;
|
|
||||||
import java.util.ArrayList;
|
|
||||||
import java.util.Arrays;
|
|
||||||
import java.util.Collections;
|
|
||||||
import java.util.Date;
|
|
||||||
import java.util.HashMap;
|
|
||||||
import java.util.HashSet;
|
|
||||||
import java.util.Iterator;
|
|
||||||
import java.util.List;
|
|
||||||
import java.util.Locale;
|
|
||||||
import java.util.Map;
|
|
||||||
import java.util.Map.Entry;
|
|
||||||
import java.util.Optional;
|
|
||||||
import java.util.Properties;
|
|
||||||
import java.util.Set;
|
|
||||||
import java.util.stream.Collectors;
|
|
||||||
|
|
||||||
import javax.annotation.Nonnull;
|
|
||||||
import javax.validation.constraints.NotNull;
|
|
||||||
|
|
||||||
import org.apache.commons.csv.CSVFormat;
|
|
||||||
import org.apache.commons.csv.CSVParser;
|
|
||||||
import org.apache.commons.csv.CSVRecord;
|
|
||||||
import org.apache.commons.csv.QuoteMode;
|
|
||||||
import org.apache.commons.io.IOUtils;
|
|
||||||
import org.apache.commons.lang3.ObjectUtils;
|
|
||||||
import org.apache.commons.lang3.StringUtils;
|
|
||||||
import org.apache.commons.lang3.Validate;
|
|
||||||
import org.hl7.fhir.instance.model.api.IIdType;
|
|
||||||
import org.hl7.fhir.r4.model.CodeSystem;
|
|
||||||
import org.hl7.fhir.r4.model.ConceptMap;
|
|
||||||
import org.hl7.fhir.r4.model.Enumerations;
|
|
||||||
import org.hl7.fhir.r4.model.ValueSet;
|
|
||||||
import org.springframework.aop.support.AopUtils;
|
|
||||||
import org.springframework.beans.factory.annotation.Autowired;
|
|
||||||
import org.xml.sax.SAXException;
|
|
||||||
|
|
||||||
import com.google.common.annotations.VisibleForTesting;
|
|
||||||
import com.google.common.base.Charsets;
|
|
||||||
|
|
||||||
import ca.uhn.fhir.context.FhirContext;
|
|
||||||
import ca.uhn.fhir.jpa.entity.TermCodeSystemVersion;
|
|
||||||
import ca.uhn.fhir.jpa.entity.TermConcept;
|
|
||||||
import ca.uhn.fhir.jpa.entity.TermConceptParentChildLink;
|
|
||||||
import ca.uhn.fhir.jpa.entity.TermConceptProperty;
|
|
||||||
import ca.uhn.fhir.jpa.term.api.ITermCodeSystemStorageSvc;
|
|
||||||
import ca.uhn.fhir.jpa.term.api.ITermDeferredStorageSvc;
|
|
||||||
import ca.uhn.fhir.jpa.term.api.ITermLoaderSvc;
|
|
||||||
import ca.uhn.fhir.jpa.term.custom.CustomTerminologySet;
|
|
||||||
import ca.uhn.fhir.jpa.term.icd10cm.Icd10CmLoader;
|
|
||||||
import ca.uhn.fhir.jpa.term.loinc.LoincAnswerListHandler;
|
|
||||||
import ca.uhn.fhir.jpa.term.loinc.LoincAnswerListLinkHandler;
|
|
||||||
import ca.uhn.fhir.jpa.term.loinc.LoincConsumerNameHandler;
|
|
||||||
import ca.uhn.fhir.jpa.term.loinc.LoincDocumentOntologyHandler;
|
|
||||||
import ca.uhn.fhir.jpa.term.loinc.LoincGroupFileHandler;
|
|
||||||
import ca.uhn.fhir.jpa.term.loinc.LoincGroupTermsFileHandler;
|
|
||||||
import ca.uhn.fhir.jpa.term.loinc.LoincHandler;
|
|
||||||
import ca.uhn.fhir.jpa.term.loinc.LoincHierarchyHandler;
|
|
||||||
import ca.uhn.fhir.jpa.term.loinc.LoincIeeeMedicalDeviceCodeHandler;
|
|
||||||
import ca.uhn.fhir.jpa.term.loinc.LoincImagingDocumentCodeHandler;
|
|
||||||
import ca.uhn.fhir.jpa.term.loinc.LoincLinguisticVariantHandler;
|
|
||||||
import ca.uhn.fhir.jpa.term.loinc.LoincLinguisticVariantsHandler;
|
|
||||||
import ca.uhn.fhir.jpa.term.loinc.LoincParentGroupFileHandler;
|
|
||||||
import ca.uhn.fhir.jpa.term.loinc.LoincPartHandler;
|
|
||||||
import ca.uhn.fhir.jpa.term.loinc.LoincPartLinkHandler;
|
|
||||||
import ca.uhn.fhir.jpa.term.loinc.LoincPartRelatedCodeMappingHandler;
|
|
||||||
import ca.uhn.fhir.jpa.term.loinc.LoincRsnaPlaybookHandler;
|
|
||||||
import ca.uhn.fhir.jpa.term.loinc.LoincTop2000LabResultsSiHandler;
|
|
||||||
import ca.uhn.fhir.jpa.term.loinc.LoincTop2000LabResultsUsHandler;
|
|
||||||
import ca.uhn.fhir.jpa.term.loinc.LoincUniversalOrderSetHandler;
|
|
||||||
import ca.uhn.fhir.jpa.term.loinc.LoincXmlFileZipContentsHandler;
|
|
||||||
import ca.uhn.fhir.jpa.term.loinc.PartTypeAndPartName;
|
|
||||||
import ca.uhn.fhir.jpa.term.snomedct.SctHandlerConcept;
|
|
||||||
import ca.uhn.fhir.jpa.term.snomedct.SctHandlerDescription;
|
|
||||||
import ca.uhn.fhir.jpa.term.snomedct.SctHandlerRelationship;
|
|
||||||
import ca.uhn.fhir.jpa.util.Counter;
|
|
||||||
import ca.uhn.fhir.rest.api.EncodingEnum;
|
|
||||||
import ca.uhn.fhir.rest.api.server.RequestDetails;
|
|
||||||
import ca.uhn.fhir.rest.server.exceptions.InternalErrorException;
|
|
||||||
import ca.uhn.fhir.rest.server.exceptions.InvalidRequestException;
|
|
||||||
import ca.uhn.fhir.util.ClasspathUtil;
|
|
||||||
import ca.uhn.fhir.util.ValidateUtil;
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* #%L
|
* #%L
|
||||||
* HAPI FHIR JPA Server
|
* HAPI FHIR JPA Server
|
||||||
|
@ -200,7 +199,7 @@ public class TermLoaderSvcImpl implements ITermLoaderSvc {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public UploadStatistics loadImgthla(List<FileDescriptor> theFiles, RequestDetails theRequestDetails) {
|
public UploadStatistics loadImgthla(List<FileDescriptor> theFiles, RequestDetails theRequestDetails) {
|
||||||
try (LoadedFileDescriptors descriptors = new LoadedFileDescriptors(theFiles)) {
|
try (LoadedFileDescriptors descriptors = getLoadedFileDescriptors(theFiles)) {
|
||||||
List<String> mandatoryFilenameFragments = Arrays.asList(
|
List<String> mandatoryFilenameFragments = Arrays.asList(
|
||||||
IMGTHLA_HLA_NOM_TXT,
|
IMGTHLA_HLA_NOM_TXT,
|
||||||
IMGTHLA_HLA_XML
|
IMGTHLA_HLA_XML
|
||||||
|
@ -213,11 +212,25 @@ public class TermLoaderSvcImpl implements ITermLoaderSvc {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@VisibleForTesting
|
||||||
|
LoadedFileDescriptors getLoadedFileDescriptors(List<FileDescriptor> theFiles) {
|
||||||
|
return new LoadedFileDescriptors(theFiles);
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public UploadStatistics loadLoinc(List<FileDescriptor> theFiles, RequestDetails theRequestDetails) {
|
public UploadStatistics loadLoinc(List<FileDescriptor> theFiles, RequestDetails theRequestDetails) {
|
||||||
try (LoadedFileDescriptors descriptors = new LoadedFileDescriptors(theFiles)) {
|
try (LoadedFileDescriptors descriptors = getLoadedFileDescriptors(theFiles)) {
|
||||||
Properties uploadProperties = getProperties(descriptors, LOINC_UPLOAD_PROPERTIES_FILE.getCode());
|
Properties uploadProperties = getProperties(descriptors, LOINC_UPLOAD_PROPERTIES_FILE.getCode());
|
||||||
|
|
||||||
|
String codeSystemVersionId = uploadProperties.getProperty(LOINC_CODESYSTEM_VERSION.getCode());
|
||||||
|
boolean isMakeCurrentVersion = Boolean.parseBoolean(
|
||||||
|
uploadProperties.getProperty(LOINC_CODESYSTEM_MAKE_CURRENT.getCode(), "true"));
|
||||||
|
|
||||||
|
if (StringUtils.isBlank(codeSystemVersionId) && ! isMakeCurrentVersion) {
|
||||||
|
throw new InvalidRequestException("'" + LOINC_CODESYSTEM_VERSION.getCode() +
|
||||||
|
"' property is required when '" + LOINC_CODESYSTEM_MAKE_CURRENT.getCode() + "' property is 'false'");
|
||||||
|
}
|
||||||
|
|
||||||
List<String> mandatoryFilenameFragments = Arrays.asList(
|
List<String> mandatoryFilenameFragments = Arrays.asList(
|
||||||
uploadProperties.getProperty(LOINC_ANSWERLIST_FILE.getCode(), LOINC_ANSWERLIST_FILE_DEFAULT.getCode()),
|
uploadProperties.getProperty(LOINC_ANSWERLIST_FILE.getCode(), LOINC_ANSWERLIST_FILE_DEFAULT.getCode()),
|
||||||
uploadProperties.getProperty(LOINC_ANSWERLIST_LINK_FILE.getCode(), LOINC_ANSWERLIST_LINK_FILE_DEFAULT.getCode()),
|
uploadProperties.getProperty(LOINC_ANSWERLIST_LINK_FILE.getCode(), LOINC_ANSWERLIST_LINK_FILE_DEFAULT.getCode()),
|
||||||
|
@ -255,21 +268,25 @@ public class TermLoaderSvcImpl implements ITermLoaderSvc {
|
||||||
|
|
||||||
ourLog.info("Beginning LOINC processing");
|
ourLog.info("Beginning LOINC processing");
|
||||||
|
|
||||||
|
if (isMakeCurrentVersion) {
|
||||||
String codeSystemVersionId = uploadProperties.getProperty(LOINC_CODESYSTEM_VERSION.getCode());
|
|
||||||
if (codeSystemVersionId != null) {
|
if (codeSystemVersionId != null) {
|
||||||
// Load the code system with version and then remove the version property.
|
|
||||||
processLoincFiles(descriptors, theRequestDetails, uploadProperties, false);
|
processLoincFiles(descriptors, theRequestDetails, uploadProperties, false);
|
||||||
uploadProperties.remove(LOINC_CODESYSTEM_VERSION.getCode());
|
uploadProperties.remove(LOINC_CODESYSTEM_VERSION.getCode());
|
||||||
}
|
}
|
||||||
// Load the same code system with null version. This will become the default version.
|
ourLog.info("Uploading CodeSystem and making it current version");
|
||||||
|
|
||||||
|
} else {
|
||||||
|
ourLog.info("Uploading CodeSystem without updating current version");
|
||||||
|
}
|
||||||
|
|
||||||
|
theRequestDetails.getUserData().put(MAKE_LOADING_VERSION_CURRENT, isMakeCurrentVersion);
|
||||||
return processLoincFiles(descriptors, theRequestDetails, uploadProperties, true);
|
return processLoincFiles(descriptors, theRequestDetails, uploadProperties, true);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public UploadStatistics loadSnomedCt(List<FileDescriptor> theFiles, RequestDetails theRequestDetails) {
|
public UploadStatistics loadSnomedCt(List<FileDescriptor> theFiles, RequestDetails theRequestDetails) {
|
||||||
try (LoadedFileDescriptors descriptors = new LoadedFileDescriptors(theFiles)) {
|
try (LoadedFileDescriptors descriptors = getLoadedFileDescriptors(theFiles)) {
|
||||||
|
|
||||||
List<String> expectedFilenameFragments = Arrays.asList(
|
List<String> expectedFilenameFragments = Arrays.asList(
|
||||||
SCT_FILE_DESCRIPTION,
|
SCT_FILE_DESCRIPTION,
|
||||||
|
@ -296,7 +313,7 @@ public class TermLoaderSvcImpl implements ITermLoaderSvc {
|
||||||
TermCodeSystemVersion codeSystemVersion = new TermCodeSystemVersion();
|
TermCodeSystemVersion codeSystemVersion = new TermCodeSystemVersion();
|
||||||
int count = 0;
|
int count = 0;
|
||||||
|
|
||||||
try (LoadedFileDescriptors compressedDescriptors = new LoadedFileDescriptors(theFiles)) {
|
try (LoadedFileDescriptors compressedDescriptors = getLoadedFileDescriptors(theFiles)) {
|
||||||
for (FileDescriptor nextDescriptor : compressedDescriptors.getUncompressedFileDescriptors()) {
|
for (FileDescriptor nextDescriptor : compressedDescriptors.getUncompressedFileDescriptors()) {
|
||||||
if (nextDescriptor.getFilename().toLowerCase(Locale.US).endsWith(".xml")) {
|
if (nextDescriptor.getFilename().toLowerCase(Locale.US).endsWith(".xml")) {
|
||||||
try (InputStream inputStream = nextDescriptor.getInputStream();
|
try (InputStream inputStream = nextDescriptor.getInputStream();
|
||||||
|
@ -319,7 +336,7 @@ public class TermLoaderSvcImpl implements ITermLoaderSvc {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public UploadStatistics loadCustom(String theSystem, List<FileDescriptor> theFiles, RequestDetails theRequestDetails) {
|
public UploadStatistics loadCustom(String theSystem, List<FileDescriptor> theFiles, RequestDetails theRequestDetails) {
|
||||||
try (LoadedFileDescriptors descriptors = new LoadedFileDescriptors(theFiles)) {
|
try (LoadedFileDescriptors descriptors = getLoadedFileDescriptors(theFiles)) {
|
||||||
Optional<String> codeSystemContent = loadFile(descriptors, CUSTOM_CODESYSTEM_JSON, CUSTOM_CODESYSTEM_XML);
|
Optional<String> codeSystemContent = loadFile(descriptors, CUSTOM_CODESYSTEM_JSON, CUSTOM_CODESYSTEM_XML);
|
||||||
CodeSystem codeSystem;
|
CodeSystem codeSystem;
|
||||||
if (codeSystemContent.isPresent()) {
|
if (codeSystemContent.isPresent()) {
|
||||||
|
@ -347,7 +364,7 @@ public class TermLoaderSvcImpl implements ITermLoaderSvc {
|
||||||
@Override
|
@Override
|
||||||
public UploadStatistics loadDeltaAdd(String theSystem, List<FileDescriptor> theFiles, RequestDetails theRequestDetails) {
|
public UploadStatistics loadDeltaAdd(String theSystem, List<FileDescriptor> theFiles, RequestDetails theRequestDetails) {
|
||||||
ourLog.info("Processing terminology delta ADD for system[{}] with files: {}", theSystem, theFiles.stream().map(t -> t.getFilename()).collect(Collectors.toList()));
|
ourLog.info("Processing terminology delta ADD for system[{}] with files: {}", theSystem, theFiles.stream().map(t -> t.getFilename()).collect(Collectors.toList()));
|
||||||
try (LoadedFileDescriptors descriptors = new LoadedFileDescriptors(theFiles)) {
|
try (LoadedFileDescriptors descriptors = getLoadedFileDescriptors(theFiles)) {
|
||||||
CustomTerminologySet terminologySet = CustomTerminologySet.load(descriptors, false);
|
CustomTerminologySet terminologySet = CustomTerminologySet.load(descriptors, false);
|
||||||
return myCodeSystemStorageSvc.applyDeltaCodeSystemsAdd(theSystem, terminologySet);
|
return myCodeSystemStorageSvc.applyDeltaCodeSystemsAdd(theSystem, terminologySet);
|
||||||
}
|
}
|
||||||
|
@ -356,7 +373,7 @@ public class TermLoaderSvcImpl implements ITermLoaderSvc {
|
||||||
@Override
|
@Override
|
||||||
public UploadStatistics loadDeltaRemove(String theSystem, List<FileDescriptor> theFiles, RequestDetails theRequestDetails) {
|
public UploadStatistics loadDeltaRemove(String theSystem, List<FileDescriptor> theFiles, RequestDetails theRequestDetails) {
|
||||||
ourLog.info("Processing terminology delta REMOVE for system[{}] with files: {}", theSystem, theFiles.stream().map(t -> t.getFilename()).collect(Collectors.toList()));
|
ourLog.info("Processing terminology delta REMOVE for system[{}] with files: {}", theSystem, theFiles.stream().map(t -> t.getFilename()).collect(Collectors.toList()));
|
||||||
try (LoadedFileDescriptors descriptors = new LoadedFileDescriptors(theFiles)) {
|
try (LoadedFileDescriptors descriptors = getLoadedFileDescriptors(theFiles)) {
|
||||||
CustomTerminologySet terminologySet = CustomTerminologySet.load(descriptors, true);
|
CustomTerminologySet terminologySet = CustomTerminologySet.load(descriptors, true);
|
||||||
return myCodeSystemStorageSvc.applyDeltaCodeSystemsRemove(theSystem, terminologySet);
|
return myCodeSystemStorageSvc.applyDeltaCodeSystemsRemove(theSystem, terminologySet);
|
||||||
}
|
}
|
||||||
|
@ -395,8 +412,9 @@ public class TermLoaderSvcImpl implements ITermLoaderSvc {
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@VisibleForTesting
|
||||||
@NotNull
|
@NotNull
|
||||||
private Properties getProperties(LoadedFileDescriptors theDescriptors, String thePropertiesFile) {
|
Properties getProperties(LoadedFileDescriptors theDescriptors, String thePropertiesFile) {
|
||||||
Properties retVal = new Properties();
|
Properties retVal = new Properties();
|
||||||
|
|
||||||
try (InputStream propertyStream = TermLoaderSvcImpl.class.getResourceAsStream("/ca/uhn/fhir/jpa/term/loinc/loincupload.properties")) {
|
try (InputStream propertyStream = TermLoaderSvcImpl.class.getResourceAsStream("/ca/uhn/fhir/jpa/term/loinc/loincupload.properties")) {
|
||||||
|
|
|
@ -21,6 +21,7 @@ package ca.uhn.fhir.jpa.term;
|
||||||
*/
|
*/
|
||||||
|
|
||||||
import ca.uhn.fhir.jpa.term.api.ITermVersionAdapterSvc;
|
import ca.uhn.fhir.jpa.term.api.ITermVersionAdapterSvc;
|
||||||
|
import ca.uhn.fhir.rest.api.server.RequestDetails;
|
||||||
import org.hl7.fhir.instance.model.api.IIdType;
|
import org.hl7.fhir.instance.model.api.IIdType;
|
||||||
import org.hl7.fhir.r4.model.CodeSystem;
|
import org.hl7.fhir.r4.model.CodeSystem;
|
||||||
import org.hl7.fhir.r4.model.ConceptMap;
|
import org.hl7.fhir.r4.model.ConceptMap;
|
||||||
|
@ -29,7 +30,7 @@ import org.hl7.fhir.r4.model.ValueSet;
|
||||||
public class TermVersionAdapterSvcDstu2 implements ITermVersionAdapterSvc {
|
public class TermVersionAdapterSvcDstu2 implements ITermVersionAdapterSvc {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public IIdType createOrUpdateCodeSystem(CodeSystem theCodeSystemResource) {
|
public IIdType createOrUpdateCodeSystem(CodeSystem theCodeSystemResource, RequestDetails theRequestDetails) {
|
||||||
throw new UnsupportedOperationException();
|
throw new UnsupportedOperationException();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -22,6 +22,7 @@ package ca.uhn.fhir.jpa.term;
|
||||||
|
|
||||||
import ca.uhn.fhir.jpa.api.dao.IFhirResourceDao;
|
import ca.uhn.fhir.jpa.api.dao.IFhirResourceDao;
|
||||||
import ca.uhn.fhir.jpa.term.api.ITermVersionAdapterSvc;
|
import ca.uhn.fhir.jpa.term.api.ITermVersionAdapterSvc;
|
||||||
|
import ca.uhn.fhir.rest.api.server.RequestDetails;
|
||||||
import ca.uhn.fhir.rest.server.exceptions.InternalErrorException;
|
import ca.uhn.fhir.rest.server.exceptions.InternalErrorException;
|
||||||
import ca.uhn.fhir.util.UrlUtil;
|
import ca.uhn.fhir.util.UrlUtil;
|
||||||
import org.hl7.fhir.dstu3.model.CodeSystem;
|
import org.hl7.fhir.dstu3.model.CodeSystem;
|
||||||
|
@ -70,7 +71,7 @@ public class TermVersionAdapterSvcDstu3 extends BaseTermVersionAdapterSvcImpl im
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public IIdType createOrUpdateCodeSystem(org.hl7.fhir.r4.model.CodeSystem theCodeSystemResource) {
|
public IIdType createOrUpdateCodeSystem(org.hl7.fhir.r4.model.CodeSystem theCodeSystemResource, RequestDetails theRequestDetails) {
|
||||||
CodeSystem resourceToStore;
|
CodeSystem resourceToStore;
|
||||||
try {
|
try {
|
||||||
resourceToStore = convertCodeSystem(theCodeSystemResource);
|
resourceToStore = convertCodeSystem(theCodeSystemResource);
|
||||||
|
@ -80,9 +81,9 @@ public class TermVersionAdapterSvcDstu3 extends BaseTermVersionAdapterSvcImpl im
|
||||||
validateCodeSystemForStorage(theCodeSystemResource);
|
validateCodeSystemForStorage(theCodeSystemResource);
|
||||||
if (isBlank(resourceToStore.getIdElement().getIdPart())) {
|
if (isBlank(resourceToStore.getIdElement().getIdPart())) {
|
||||||
String matchUrl = "CodeSystem?url=" + UrlUtil.escapeUrlParam(theCodeSystemResource.getUrl());
|
String matchUrl = "CodeSystem?url=" + UrlUtil.escapeUrlParam(theCodeSystemResource.getUrl());
|
||||||
return myCodeSystemResourceDao.update(resourceToStore, matchUrl).getId();
|
return myCodeSystemResourceDao.update(resourceToStore, matchUrl, theRequestDetails).getId();
|
||||||
} else {
|
} else {
|
||||||
return myCodeSystemResourceDao.update(resourceToStore).getId();
|
return myCodeSystemResourceDao.update(resourceToStore, theRequestDetails).getId();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -22,6 +22,7 @@ package ca.uhn.fhir.jpa.term;
|
||||||
|
|
||||||
import ca.uhn.fhir.jpa.api.dao.IFhirResourceDao;
|
import ca.uhn.fhir.jpa.api.dao.IFhirResourceDao;
|
||||||
import ca.uhn.fhir.jpa.term.api.ITermVersionAdapterSvc;
|
import ca.uhn.fhir.jpa.term.api.ITermVersionAdapterSvc;
|
||||||
|
import ca.uhn.fhir.rest.api.server.RequestDetails;
|
||||||
import ca.uhn.fhir.util.UrlUtil;
|
import ca.uhn.fhir.util.UrlUtil;
|
||||||
import org.hl7.fhir.instance.model.api.IIdType;
|
import org.hl7.fhir.instance.model.api.IIdType;
|
||||||
import org.hl7.fhir.r4.model.CodeSystem;
|
import org.hl7.fhir.r4.model.CodeSystem;
|
||||||
|
@ -59,13 +60,13 @@ public class TermVersionAdapterSvcR4 extends BaseTermVersionAdapterSvcImpl imple
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public IIdType createOrUpdateCodeSystem(org.hl7.fhir.r4.model.CodeSystem theCodeSystemResource) {
|
public IIdType createOrUpdateCodeSystem(org.hl7.fhir.r4.model.CodeSystem theCodeSystemResource, RequestDetails theRequestDetails) {
|
||||||
validateCodeSystemForStorage(theCodeSystemResource);
|
validateCodeSystemForStorage(theCodeSystemResource);
|
||||||
if (isBlank(theCodeSystemResource.getIdElement().getIdPart())) {
|
if (isBlank(theCodeSystemResource.getIdElement().getIdPart())) {
|
||||||
String matchUrl = "CodeSystem?url=" + UrlUtil.escapeUrlParam(theCodeSystemResource.getUrl());
|
String matchUrl = "CodeSystem?url=" + UrlUtil.escapeUrlParam(theCodeSystemResource.getUrl());
|
||||||
return myCodeSystemResourceDao.update(theCodeSystemResource, matchUrl).getId();
|
return myCodeSystemResourceDao.update(theCodeSystemResource, matchUrl, theRequestDetails).getId();
|
||||||
} else {
|
} else {
|
||||||
return myCodeSystemResourceDao.update(theCodeSystemResource).getId();
|
return myCodeSystemResourceDao.update(theCodeSystemResource, theRequestDetails).getId();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -22,6 +22,7 @@ package ca.uhn.fhir.jpa.term;
|
||||||
|
|
||||||
import ca.uhn.fhir.jpa.api.dao.IFhirResourceDao;
|
import ca.uhn.fhir.jpa.api.dao.IFhirResourceDao;
|
||||||
import ca.uhn.fhir.jpa.term.api.ITermVersionAdapterSvc;
|
import ca.uhn.fhir.jpa.term.api.ITermVersionAdapterSvc;
|
||||||
|
import ca.uhn.fhir.rest.api.server.RequestDetails;
|
||||||
import ca.uhn.fhir.util.UrlUtil;
|
import ca.uhn.fhir.util.UrlUtil;
|
||||||
import org.hl7.fhir.instance.model.api.IIdType;
|
import org.hl7.fhir.instance.model.api.IIdType;
|
||||||
import org.hl7.fhir.r5.model.CodeSystem;
|
import org.hl7.fhir.r5.model.CodeSystem;
|
||||||
|
@ -59,15 +60,15 @@ public class TermVersionAdapterSvcR5 extends BaseTermVersionAdapterSvcImpl imple
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public IIdType createOrUpdateCodeSystem(org.hl7.fhir.r4.model.CodeSystem theCodeSystemResource) {
|
public IIdType createOrUpdateCodeSystem(org.hl7.fhir.r4.model.CodeSystem theCodeSystemResource, RequestDetails theRequestDetails) {
|
||||||
validateCodeSystemForStorage(theCodeSystemResource);
|
validateCodeSystemForStorage(theCodeSystemResource);
|
||||||
|
|
||||||
CodeSystem codeSystemR4 = org.hl7.fhir.convertors.conv40_50.CodeSystem40_50.convertCodeSystem(theCodeSystemResource);
|
CodeSystem codeSystemR4 = org.hl7.fhir.convertors.conv40_50.CodeSystem40_50.convertCodeSystem(theCodeSystemResource);
|
||||||
if (isBlank(theCodeSystemResource.getIdElement().getIdPart())) {
|
if (isBlank(theCodeSystemResource.getIdElement().getIdPart())) {
|
||||||
String matchUrl = "CodeSystem?url=" + UrlUtil.escapeUrlParam(theCodeSystemResource.getUrl());
|
String matchUrl = "CodeSystem?url=" + UrlUtil.escapeUrlParam(theCodeSystemResource.getUrl());
|
||||||
return myCodeSystemResourceDao.update(codeSystemR4, matchUrl).getId();
|
return myCodeSystemResourceDao.update(codeSystemR4, matchUrl, theRequestDetails).getId();
|
||||||
} else {
|
} else {
|
||||||
return myCodeSystemResourceDao.update(codeSystemR4).getId();
|
return myCodeSystemResourceDao.update(codeSystemR4, theRequestDetails).getId();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -20,7 +20,6 @@ package ca.uhn.fhir.jpa.term.api;
|
||||||
* #L%
|
* #L%
|
||||||
*/
|
*/
|
||||||
|
|
||||||
import ca.uhn.fhir.rest.api.server.storage.ResourcePersistentId;
|
|
||||||
import ca.uhn.fhir.jpa.entity.TermCodeSystem;
|
import ca.uhn.fhir.jpa.entity.TermCodeSystem;
|
||||||
import ca.uhn.fhir.jpa.entity.TermCodeSystemVersion;
|
import ca.uhn.fhir.jpa.entity.TermCodeSystemVersion;
|
||||||
import ca.uhn.fhir.jpa.entity.TermConcept;
|
import ca.uhn.fhir.jpa.entity.TermConcept;
|
||||||
|
@ -28,10 +27,12 @@ import ca.uhn.fhir.jpa.model.entity.ResourceTable;
|
||||||
import ca.uhn.fhir.jpa.term.UploadStatistics;
|
import ca.uhn.fhir.jpa.term.UploadStatistics;
|
||||||
import ca.uhn.fhir.jpa.term.custom.CustomTerminologySet;
|
import ca.uhn.fhir.jpa.term.custom.CustomTerminologySet;
|
||||||
import ca.uhn.fhir.rest.api.server.RequestDetails;
|
import ca.uhn.fhir.rest.api.server.RequestDetails;
|
||||||
|
import ca.uhn.fhir.rest.api.server.storage.ResourcePersistentId;
|
||||||
import org.hl7.fhir.instance.model.api.IIdType;
|
import org.hl7.fhir.instance.model.api.IIdType;
|
||||||
import org.hl7.fhir.r4.model.CodeSystem;
|
import org.hl7.fhir.r4.model.CodeSystem;
|
||||||
import org.hl7.fhir.r4.model.ValueSet;
|
import org.hl7.fhir.r4.model.ValueSet;
|
||||||
|
|
||||||
|
import javax.transaction.Transactional;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -39,18 +40,48 @@ import java.util.List;
|
||||||
*/
|
*/
|
||||||
public interface ITermCodeSystemStorageSvc {
|
public interface ITermCodeSystemStorageSvc {
|
||||||
|
|
||||||
|
static final String MAKE_LOADING_VERSION_CURRENT = "make.loading.version.current";
|
||||||
|
|
||||||
void deleteCodeSystem(TermCodeSystem theCodeSystem);
|
void deleteCodeSystem(TermCodeSystem theCodeSystem);
|
||||||
|
|
||||||
void deleteCodeSystemVersion(TermCodeSystemVersion theCodeSystemVersion);
|
void deleteCodeSystemVersion(TermCodeSystemVersion theCodeSystemVersion);
|
||||||
|
|
||||||
void storeNewCodeSystemVersion(ResourcePersistentId theCodeSystemResourcePid, String theSystemUri, String theSystemName, String theSystemVersionId, TermCodeSystemVersion theCodeSystemVersion, ResourceTable theCodeSystemResourceTable);
|
|
||||||
|
void storeNewCodeSystemVersion(ResourcePersistentId theCodeSystemResourcePid, String theSystemUri, String theSystemName,
|
||||||
|
String theSystemVersionId, TermCodeSystemVersion theCodeSystemVersion, ResourceTable theCodeSystemResourceTable,
|
||||||
|
RequestDetails theRequestDetails);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Default implementation supports previous signature of method which was added RequestDetails parameter
|
||||||
|
*/
|
||||||
|
@Transactional
|
||||||
|
default void storeNewCodeSystemVersion(ResourcePersistentId theCodeSystemResourcePid, String theSystemUri, String theSystemName,
|
||||||
|
String theSystemVersionId, TermCodeSystemVersion theCodeSystemVersion, ResourceTable theCodeSystemResourceTable) {
|
||||||
|
|
||||||
|
storeNewCodeSystemVersion(theCodeSystemResourcePid, theSystemUri, theSystemName, theSystemVersionId,
|
||||||
|
theCodeSystemVersion, theCodeSystemResourceTable, null);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @return Returns the ID of the created/updated code system
|
* @return Returns the ID of the created/updated code system
|
||||||
*/
|
*/
|
||||||
IIdType storeNewCodeSystemVersion(org.hl7.fhir.r4.model.CodeSystem theCodeSystemResource, TermCodeSystemVersion theCodeSystemVersion, RequestDetails theRequestDetails, List<ValueSet> theValueSets, List<org.hl7.fhir.r4.model.ConceptMap> theConceptMaps);
|
IIdType storeNewCodeSystemVersion(org.hl7.fhir.r4.model.CodeSystem theCodeSystemResource,
|
||||||
|
TermCodeSystemVersion theCodeSystemVersion, RequestDetails theRequestDetails, List<ValueSet> theValueSets,
|
||||||
|
List<org.hl7.fhir.r4.model.ConceptMap> theConceptMaps);
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
void storeNewCodeSystemVersionIfNeeded(CodeSystem theCodeSystem, ResourceTable theResourceEntity, RequestDetails theRequestDetails);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Default implementation supports previous signature of method which was added RequestDetails parameter
|
||||||
|
*/
|
||||||
|
default void storeNewCodeSystemVersionIfNeeded(CodeSystem theCodeSystem, ResourceTable theResourceEntity) {
|
||||||
|
storeNewCodeSystemVersionIfNeeded(theCodeSystem, theResourceEntity, null);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
void storeNewCodeSystemVersionIfNeeded(CodeSystem theCodeSystem, ResourceTable theResourceEntity);
|
|
||||||
|
|
||||||
UploadStatistics applyDeltaCodeSystemsAdd(String theSystem, CustomTerminologySet theAdditions);
|
UploadStatistics applyDeltaCodeSystemsAdd(String theSystem, CustomTerminologySet theAdditions);
|
||||||
|
|
||||||
|
|
|
@ -20,6 +20,7 @@ package ca.uhn.fhir.jpa.term.api;
|
||||||
* #L%
|
* #L%
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
import ca.uhn.fhir.rest.api.server.RequestDetails;
|
||||||
import org.hl7.fhir.instance.model.api.IIdType;
|
import org.hl7.fhir.instance.model.api.IIdType;
|
||||||
import org.hl7.fhir.r4.model.CodeSystem;
|
import org.hl7.fhir.r4.model.CodeSystem;
|
||||||
import org.hl7.fhir.r4.model.ConceptMap;
|
import org.hl7.fhir.r4.model.ConceptMap;
|
||||||
|
@ -32,7 +33,11 @@ import org.hl7.fhir.r4.model.ValueSet;
|
||||||
*/
|
*/
|
||||||
public interface ITermVersionAdapterSvc {
|
public interface ITermVersionAdapterSvc {
|
||||||
|
|
||||||
IIdType createOrUpdateCodeSystem(CodeSystem theCodeSystemResource);
|
default IIdType createOrUpdateCodeSystem(CodeSystem theCodeSystemResource) {
|
||||||
|
return createOrUpdateCodeSystem(theCodeSystemResource, null);
|
||||||
|
}
|
||||||
|
|
||||||
|
IIdType createOrUpdateCodeSystem(CodeSystem theCodeSystemResource, RequestDetails theRequestDetails);
|
||||||
|
|
||||||
void createOrUpdateConceptMap(ConceptMap theNextConceptMap);
|
void createOrUpdateConceptMap(ConceptMap theNextConceptMap);
|
||||||
|
|
||||||
|
|
|
@ -101,6 +101,9 @@ public enum LoincUploadPropertiesEnum {
|
||||||
// This is the version identifier for the LOINC code system
|
// This is the version identifier for the LOINC code system
|
||||||
LOINC_CODESYSTEM_VERSION("loinc.codesystem.version"),
|
LOINC_CODESYSTEM_VERSION("loinc.codesystem.version"),
|
||||||
|
|
||||||
|
// Indicates if loading version has to become current
|
||||||
|
LOINC_CODESYSTEM_MAKE_CURRENT("loinc.codesystem.make.current"),
|
||||||
|
|
||||||
// This is the version identifier for the answer list file
|
// This is the version identifier for the answer list file
|
||||||
LOINC_ANSWERLIST_VERSION("loinc.answerlist.version"),
|
LOINC_ANSWERLIST_VERSION("loinc.answerlist.version"),
|
||||||
|
|
||||||
|
|
|
@ -65,6 +65,10 @@ loinc.universal.lab.order.valueset.file=AccessoryFiles/LoincUniversalLabOrdersVa
|
||||||
## Key may be omitted if only a single version of LOINC is being kept.
|
## Key may be omitted if only a single version of LOINC is being kept.
|
||||||
#loinc.codesystem.version=2.68
|
#loinc.codesystem.version=2.68
|
||||||
|
|
||||||
|
# Indicates if version being loaded has to become current
|
||||||
|
## Default is true
|
||||||
|
loinc.codesystem.make.current=true
|
||||||
|
|
||||||
# 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=Beta.1
|
||||||
|
|
|
@ -29,6 +29,7 @@ import org.hl7.fhir.r4.model.ValueSet;
|
||||||
import org.hl7.fhir.r4.model.ValueSet.ConceptReferenceComponent;
|
import org.hl7.fhir.r4.model.ValueSet.ConceptReferenceComponent;
|
||||||
import org.junit.jupiter.api.AfterAll;
|
import org.junit.jupiter.api.AfterAll;
|
||||||
import org.junit.jupiter.api.AfterEach;
|
import org.junit.jupiter.api.AfterEach;
|
||||||
|
import org.junit.jupiter.api.BeforeEach;
|
||||||
import org.junit.jupiter.api.Test;
|
import org.junit.jupiter.api.Test;
|
||||||
import org.junit.jupiter.api.extension.ExtendWith;
|
import org.junit.jupiter.api.extension.ExtendWith;
|
||||||
import org.mockito.Answers;
|
import org.mockito.Answers;
|
||||||
|
@ -42,8 +43,10 @@ import org.springframework.transaction.PlatformTransactionManager;
|
||||||
import java.util.Set;
|
import java.util.Set;
|
||||||
import java.util.stream.Collectors;
|
import java.util.stream.Collectors;
|
||||||
|
|
||||||
|
import static ca.uhn.fhir.jpa.term.api.ITermCodeSystemStorageSvc.MAKE_LOADING_VERSION_CURRENT;
|
||||||
import static org.hamcrest.MatcherAssert.assertThat;
|
import static org.hamcrest.MatcherAssert.assertThat;
|
||||||
import static org.hamcrest.Matchers.containsInAnyOrder;
|
import static org.hamcrest.Matchers.containsInAnyOrder;
|
||||||
|
import static org.mockito.Mockito.when;
|
||||||
|
|
||||||
@ExtendWith(SpringExtension.class)
|
@ExtendWith(SpringExtension.class)
|
||||||
@RequiresDocker
|
@RequiresDocker
|
||||||
|
@ -83,6 +86,13 @@ public class FhirResourceDaoR4TerminologyElasticsearchIT extends BaseJpaTest {
|
||||||
@Autowired
|
@Autowired
|
||||||
private IBulkDataExportSvc myBulkDataExportSvc;
|
private IBulkDataExportSvc myBulkDataExportSvc;
|
||||||
|
|
||||||
|
|
||||||
|
@BeforeEach
|
||||||
|
public void beforeEach() {
|
||||||
|
when(mySrd.getUserData().getOrDefault(MAKE_LOADING_VERSION_CURRENT, Boolean.TRUE)).thenReturn(Boolean.TRUE);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testExpandWithIncludeContainingDashesInInclude() {
|
public void testExpandWithIncludeContainingDashesInInclude() {
|
||||||
CodeSystem codeSystem = new CodeSystem();
|
CodeSystem codeSystem = new CodeSystem();
|
||||||
|
|
|
@ -1,9 +1,53 @@
|
||||||
package ca.uhn.fhir.jpa.term;
|
package ca.uhn.fhir.jpa.term;
|
||||||
|
|
||||||
|
import ca.uhn.fhir.context.FhirContext;
|
||||||
|
import ca.uhn.fhir.context.FhirVersionEnum;
|
||||||
|
import ca.uhn.fhir.jpa.entity.TermCodeSystemVersion;
|
||||||
|
import ca.uhn.fhir.jpa.entity.TermConcept;
|
||||||
|
import ca.uhn.fhir.jpa.entity.TermConceptDesignation;
|
||||||
|
import ca.uhn.fhir.jpa.entity.TermConceptProperty;
|
||||||
|
import ca.uhn.fhir.jpa.model.util.JpaConstants;
|
||||||
|
import ca.uhn.fhir.jpa.term.api.ITermCodeSystemStorageSvc;
|
||||||
|
import ca.uhn.fhir.jpa.term.api.ITermDeferredStorageSvc;
|
||||||
|
import ca.uhn.fhir.jpa.term.api.ITermLoaderSvc;
|
||||||
|
import ca.uhn.fhir.jpa.term.loinc.LoincDocumentOntologyHandler;
|
||||||
|
import ca.uhn.fhir.jpa.term.loinc.LoincIeeeMedicalDeviceCodeHandler;
|
||||||
|
import ca.uhn.fhir.jpa.term.loinc.LoincImagingDocumentCodeHandler;
|
||||||
|
import ca.uhn.fhir.jpa.term.loinc.LoincPartRelatedCodeMappingHandler;
|
||||||
|
import ca.uhn.fhir.jpa.term.loinc.LoincRsnaPlaybookHandler;
|
||||||
|
import ca.uhn.fhir.jpa.term.loinc.LoincTop2000LabResultsSiHandler;
|
||||||
|
import ca.uhn.fhir.jpa.term.loinc.LoincTop2000LabResultsUsHandler;
|
||||||
|
import ca.uhn.fhir.jpa.term.loinc.LoincUniversalOrderSetHandler;
|
||||||
|
import ca.uhn.fhir.rest.api.server.RequestDetails;
|
||||||
|
import ca.uhn.fhir.rest.server.exceptions.InvalidRequestException;
|
||||||
|
import ca.uhn.fhir.rest.server.exceptions.UnprocessableEntityException;
|
||||||
|
import ca.uhn.fhir.rest.server.servlet.ServletRequestDetails;
|
||||||
|
import org.hl7.fhir.r4.model.CodeSystem;
|
||||||
|
import org.hl7.fhir.r4.model.ConceptMap;
|
||||||
|
import org.hl7.fhir.r4.model.Enumerations;
|
||||||
|
import org.hl7.fhir.r4.model.ValueSet;
|
||||||
|
import org.junit.jupiter.api.Assertions;
|
||||||
|
import org.junit.jupiter.api.BeforeEach;
|
||||||
|
import org.junit.jupiter.api.Nested;
|
||||||
|
import org.junit.jupiter.api.Test;
|
||||||
|
import org.mockito.ArgumentCaptor;
|
||||||
|
import org.mockito.Captor;
|
||||||
|
import org.mockito.Mock;
|
||||||
|
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.Collection;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.Map;
|
||||||
|
import java.util.Properties;
|
||||||
|
|
||||||
|
import static ca.uhn.fhir.jpa.term.api.ITermCodeSystemStorageSvc.MAKE_LOADING_VERSION_CURRENT;
|
||||||
import static ca.uhn.fhir.jpa.term.loinc.LoincUploadPropertiesEnum.LOINC_ANSWERLIST_DUPLICATE_FILE_DEFAULT;
|
import static ca.uhn.fhir.jpa.term.loinc.LoincUploadPropertiesEnum.LOINC_ANSWERLIST_DUPLICATE_FILE_DEFAULT;
|
||||||
import static ca.uhn.fhir.jpa.term.loinc.LoincUploadPropertiesEnum.LOINC_ANSWERLIST_FILE_DEFAULT;
|
import static ca.uhn.fhir.jpa.term.loinc.LoincUploadPropertiesEnum.LOINC_ANSWERLIST_FILE_DEFAULT;
|
||||||
import static ca.uhn.fhir.jpa.term.loinc.LoincUploadPropertiesEnum.LOINC_ANSWERLIST_LINK_DUPLICATE_FILE_DEFAULT;
|
import static ca.uhn.fhir.jpa.term.loinc.LoincUploadPropertiesEnum.LOINC_ANSWERLIST_LINK_DUPLICATE_FILE_DEFAULT;
|
||||||
import static ca.uhn.fhir.jpa.term.loinc.LoincUploadPropertiesEnum.LOINC_ANSWERLIST_LINK_FILE_DEFAULT;
|
import static ca.uhn.fhir.jpa.term.loinc.LoincUploadPropertiesEnum.LOINC_ANSWERLIST_LINK_FILE_DEFAULT;
|
||||||
|
import static ca.uhn.fhir.jpa.term.loinc.LoincUploadPropertiesEnum.LOINC_CODESYSTEM_MAKE_CURRENT;
|
||||||
|
import static ca.uhn.fhir.jpa.term.loinc.LoincUploadPropertiesEnum.LOINC_CODESYSTEM_VERSION;
|
||||||
import static ca.uhn.fhir.jpa.term.loinc.LoincUploadPropertiesEnum.LOINC_CONSUMER_NAME_FILE_DEFAULT;
|
import static ca.uhn.fhir.jpa.term.loinc.LoincUploadPropertiesEnum.LOINC_CONSUMER_NAME_FILE_DEFAULT;
|
||||||
import static ca.uhn.fhir.jpa.term.loinc.LoincUploadPropertiesEnum.LOINC_DOCUMENT_ONTOLOGY_FILE_DEFAULT;
|
import static ca.uhn.fhir.jpa.term.loinc.LoincUploadPropertiesEnum.LOINC_DOCUMENT_ONTOLOGY_FILE_DEFAULT;
|
||||||
import static ca.uhn.fhir.jpa.term.loinc.LoincUploadPropertiesEnum.LOINC_DUPLICATE_FILE_DEFAULT;
|
import static ca.uhn.fhir.jpa.term.loinc.LoincUploadPropertiesEnum.LOINC_DUPLICATE_FILE_DEFAULT;
|
||||||
|
@ -30,49 +74,19 @@ import static org.hamcrest.MatcherAssert.assertThat;
|
||||||
import static org.hamcrest.Matchers.contains;
|
import static org.hamcrest.Matchers.contains;
|
||||||
import static org.hamcrest.Matchers.containsString;
|
import static org.hamcrest.Matchers.containsString;
|
||||||
import static org.junit.jupiter.api.Assertions.assertEquals;
|
import static org.junit.jupiter.api.Assertions.assertEquals;
|
||||||
|
import static org.junit.jupiter.api.Assertions.assertFalse;
|
||||||
import static org.junit.jupiter.api.Assertions.assertNull;
|
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;
|
||||||
|
import static org.mockito.ArgumentMatchers.eq;
|
||||||
|
import static org.mockito.Mockito.doReturn;
|
||||||
|
import static org.mockito.Mockito.mock;
|
||||||
import static org.mockito.Mockito.reset;
|
import static org.mockito.Mockito.reset;
|
||||||
|
import static org.mockito.Mockito.spy;
|
||||||
import static org.mockito.Mockito.times;
|
import static org.mockito.Mockito.times;
|
||||||
import static org.mockito.Mockito.verify;
|
import static org.mockito.Mockito.verify;
|
||||||
|
|
||||||
import java.io.IOException;
|
|
||||||
import java.util.ArrayList;
|
|
||||||
import java.util.Collection;
|
|
||||||
import java.util.List;
|
|
||||||
import java.util.Map;
|
|
||||||
|
|
||||||
import org.hl7.fhir.r4.model.CodeSystem;
|
|
||||||
import org.hl7.fhir.r4.model.ConceptMap;
|
|
||||||
import org.hl7.fhir.r4.model.Enumerations;
|
|
||||||
import org.hl7.fhir.r4.model.ValueSet;
|
|
||||||
import org.junit.jupiter.api.BeforeEach;
|
|
||||||
import org.junit.jupiter.api.Test;
|
|
||||||
import org.mockito.ArgumentCaptor;
|
|
||||||
import org.mockito.Captor;
|
|
||||||
import org.mockito.Mock;
|
|
||||||
|
|
||||||
import ca.uhn.fhir.context.FhirContext;
|
|
||||||
import ca.uhn.fhir.context.FhirVersionEnum;
|
|
||||||
import ca.uhn.fhir.jpa.entity.TermConcept;
|
|
||||||
import ca.uhn.fhir.jpa.entity.TermConceptDesignation;
|
|
||||||
import ca.uhn.fhir.jpa.entity.TermConceptProperty;
|
|
||||||
import ca.uhn.fhir.jpa.term.api.ITermCodeSystemStorageSvc;
|
|
||||||
import ca.uhn.fhir.jpa.term.api.ITermDeferredStorageSvc;
|
|
||||||
import ca.uhn.fhir.jpa.term.api.ITermLoaderSvc;
|
|
||||||
import ca.uhn.fhir.jpa.term.loinc.LoincDocumentOntologyHandler;
|
|
||||||
import ca.uhn.fhir.jpa.term.loinc.LoincIeeeMedicalDeviceCodeHandler;
|
|
||||||
import ca.uhn.fhir.jpa.term.loinc.LoincImagingDocumentCodeHandler;
|
|
||||||
import ca.uhn.fhir.jpa.term.loinc.LoincPartRelatedCodeMappingHandler;
|
|
||||||
import ca.uhn.fhir.jpa.term.loinc.LoincRsnaPlaybookHandler;
|
|
||||||
import ca.uhn.fhir.jpa.term.loinc.LoincTop2000LabResultsSiHandler;
|
|
||||||
import ca.uhn.fhir.jpa.term.loinc.LoincTop2000LabResultsUsHandler;
|
|
||||||
import ca.uhn.fhir.jpa.term.loinc.LoincUniversalOrderSetHandler;
|
|
||||||
import ca.uhn.fhir.rest.api.server.RequestDetails;
|
|
||||||
import ca.uhn.fhir.rest.server.exceptions.UnprocessableEntityException;
|
|
||||||
|
|
||||||
public class TerminologyLoaderSvcLoincTest extends BaseLoaderTest {
|
public class TerminologyLoaderSvcLoincTest extends BaseLoaderTest {
|
||||||
private static final org.slf4j.Logger ourLog = org.slf4j.LoggerFactory.getLogger(TerminologyLoaderSvcLoincTest.class);
|
private static final org.slf4j.Logger ourLog = org.slf4j.LoggerFactory.getLogger(TerminologyLoaderSvcLoincTest.class);
|
||||||
private TermLoaderSvcImpl mySvc;
|
private TermLoaderSvcImpl mySvc;
|
||||||
|
@ -99,6 +113,8 @@ public class TerminologyLoaderSvcLoincTest extends BaseLoaderTest {
|
||||||
private ArgumentCaptor<List<ConceptMap>> myConceptMapCaptor_267_second;
|
private ArgumentCaptor<List<ConceptMap>> myConceptMapCaptor_267_second;
|
||||||
@Captor
|
@Captor
|
||||||
private ArgumentCaptor<List<ConceptMap>> myConceptMapCaptor_268;
|
private ArgumentCaptor<List<ConceptMap>> myConceptMapCaptor_268;
|
||||||
|
@Captor
|
||||||
|
private ArgumentCaptor<RequestDetails> myRequestDetailsCaptor;
|
||||||
private ZipCollectionBuilder myFiles;
|
private ZipCollectionBuilder myFiles;
|
||||||
@Mock
|
@Mock
|
||||||
private ITermDeferredStorageSvc myTermDeferredStorageSvc;
|
private ITermDeferredStorageSvc myTermDeferredStorageSvc;
|
||||||
|
@ -822,6 +838,110 @@ public class TerminologyLoaderSvcLoincTest extends BaseLoaderTest {
|
||||||
assertEquals("LP52960-9", doublyNestedChildCode.getChildren().get(2).getChild().getCode());
|
assertEquals("LP52960-9", doublyNestedChildCode.getChildren().get(2).getChild().getCode());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
@Nested
|
||||||
|
public class LoadLoincCurrentVersion {
|
||||||
|
private TermLoaderSvcImpl testedSvc;
|
||||||
|
private final Properties testProps = new Properties();
|
||||||
|
|
||||||
|
@Mock private final LoadedFileDescriptors mockFileDescriptors = mock(LoadedFileDescriptors.class);
|
||||||
|
@SuppressWarnings("unchecked")
|
||||||
|
@Mock private final List<ITermLoaderSvc.FileDescriptor> mockFileDescriptorList = mock(List.class);
|
||||||
|
@Mock private final ITermCodeSystemStorageSvc mockCodeSystemStorageSvc = mock(ITermCodeSystemStorageSvc.class);
|
||||||
|
private final RequestDetails requestDetails = new ServletRequestDetails();
|
||||||
|
|
||||||
|
|
||||||
|
@BeforeEach
|
||||||
|
void beforeEach() {
|
||||||
|
testedSvc = spy(mySvc);
|
||||||
|
doReturn(testProps).when(testedSvc).getProperties(any(), eq(LOINC_UPLOAD_PROPERTIES_FILE.getCode()));
|
||||||
|
requestDetails.setOperation(JpaConstants.OPERATION_UPLOAD_EXTERNAL_CODE_SYSTEM);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testDontMakeCurrentVersion() throws IOException {
|
||||||
|
addLoincMandatoryFilesToZip(myFiles);
|
||||||
|
testProps.put(LOINC_CODESYSTEM_MAKE_CURRENT.getCode(), "false");
|
||||||
|
testProps.put(LOINC_CODESYSTEM_VERSION.getCode(), "27.0");
|
||||||
|
|
||||||
|
testedSvc.loadLoinc(myFiles.getFiles(), requestDetails);
|
||||||
|
|
||||||
|
verify(myTermCodeSystemStorageSvc, times(1)).storeNewCodeSystemVersion(
|
||||||
|
any(CodeSystem.class), any(TermCodeSystemVersion.class), myRequestDetailsCaptor.capture(), any(), any());
|
||||||
|
|
||||||
|
myRequestDetailsCaptor.getAllValues().forEach( rd ->
|
||||||
|
assertFalse(rd.getUserData() == null ||
|
||||||
|
(boolean) requestDetails.getUserData().getOrDefault(MAKE_LOADING_VERSION_CURRENT, Boolean.TRUE))
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testMakeCurrentVersionPropertySet() {
|
||||||
|
testProps.put(LOINC_CODESYSTEM_MAKE_CURRENT.getCode(), "true");
|
||||||
|
testProps.put(LOINC_CODESYSTEM_VERSION.getCode(), "27.0");
|
||||||
|
doReturn(mockFileDescriptors).when(testedSvc).getLoadedFileDescriptors(mockFileDescriptorList);
|
||||||
|
doReturn(mock(UploadStatistics.class)).when(testedSvc).processLoincFiles(
|
||||||
|
eq(mockFileDescriptors), eq(requestDetails), eq(testProps), any());
|
||||||
|
|
||||||
|
testedSvc.loadLoinc(mockFileDescriptorList, requestDetails);
|
||||||
|
|
||||||
|
boolean isMakeCurrent = requestDetails.getUserData() == null ||
|
||||||
|
(boolean) requestDetails.getUserData().getOrDefault(MAKE_LOADING_VERSION_CURRENT, Boolean.TRUE);
|
||||||
|
assertTrue(isMakeCurrent);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testMakeCurrentVersionByDefaultPropertySet() {
|
||||||
|
testProps.put(LOINC_CODESYSTEM_VERSION.getCode(), "27.0");
|
||||||
|
doReturn(mockFileDescriptors).when(testedSvc).getLoadedFileDescriptors(mockFileDescriptorList);
|
||||||
|
doReturn(mock(UploadStatistics.class)).when(testedSvc).processLoincFiles(
|
||||||
|
eq(mockFileDescriptors), eq(requestDetails), eq(testProps), any());
|
||||||
|
|
||||||
|
testedSvc.loadLoinc(mockFileDescriptorList, requestDetails);
|
||||||
|
|
||||||
|
boolean isMakeCurrent = requestDetails.getUserData() == null ||
|
||||||
|
(boolean) requestDetails.getUserData().getOrDefault(MAKE_LOADING_VERSION_CURRENT, Boolean.TRUE);
|
||||||
|
assertTrue(isMakeCurrent);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testDontMakeCurrentVersionPropertySet() {
|
||||||
|
testProps.put(LOINC_CODESYSTEM_MAKE_CURRENT.getCode(), "false");
|
||||||
|
testProps.put(LOINC_CODESYSTEM_VERSION.getCode(), "27.0");
|
||||||
|
doReturn(mockFileDescriptors).when(testedSvc).getLoadedFileDescriptors(mockFileDescriptorList);
|
||||||
|
doReturn(mock(UploadStatistics.class)).when(testedSvc).processLoincFiles(
|
||||||
|
eq(mockFileDescriptors), eq(requestDetails), eq(testProps), any());
|
||||||
|
|
||||||
|
testedSvc.loadLoinc(mockFileDescriptorList, requestDetails);
|
||||||
|
|
||||||
|
boolean isMakeCurrent = requestDetails.getUserData() == null ||
|
||||||
|
(boolean) requestDetails.getUserData().getOrDefault(MAKE_LOADING_VERSION_CURRENT, Boolean.TRUE);
|
||||||
|
assertFalse(isMakeCurrent);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testNoVersionAndNoMakeCurrentThrows() {
|
||||||
|
testProps.put(LOINC_CODESYSTEM_MAKE_CURRENT.getCode(), "false");
|
||||||
|
doReturn(mockFileDescriptors).when(testedSvc).getLoadedFileDescriptors(mockFileDescriptorList);
|
||||||
|
|
||||||
|
InvalidRequestException thrown = Assertions.assertThrows(InvalidRequestException.class,
|
||||||
|
() -> testedSvc.loadLoinc(mockFileDescriptorList, mySrd) );
|
||||||
|
|
||||||
|
assertEquals("'" + LOINC_CODESYSTEM_VERSION.getCode() + "' property is required when '" +
|
||||||
|
LOINC_CODESYSTEM_MAKE_CURRENT.getCode() + "' property is 'false'", thrown.getMessage());
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
private static void verifyConsumerName(Collection<TermConceptDesignation> designationList, String theConsumerName) {
|
private static void verifyConsumerName(Collection<TermConceptDesignation> designationList, String theConsumerName) {
|
||||||
|
|
||||||
TermConceptDesignation consumerNameDesignation = null;
|
TermConceptDesignation consumerNameDesignation = null;
|
||||||
|
|
|
@ -30,6 +30,7 @@ import org.hl7.fhir.r4.model.CodeableConcept;
|
||||||
import org.hl7.fhir.r4.model.Coding;
|
import org.hl7.fhir.r4.model.Coding;
|
||||||
import org.hl7.fhir.r4.model.ValueSet;
|
import org.hl7.fhir.r4.model.ValueSet;
|
||||||
import org.junit.jupiter.api.AfterEach;
|
import org.junit.jupiter.api.AfterEach;
|
||||||
|
import org.junit.jupiter.api.BeforeEach;
|
||||||
import org.junit.jupiter.api.Test;
|
import org.junit.jupiter.api.Test;
|
||||||
import org.junit.jupiter.api.extension.ExtendWith;
|
import org.junit.jupiter.api.extension.ExtendWith;
|
||||||
import org.mockito.Answers;
|
import org.mockito.Answers;
|
||||||
|
@ -40,6 +41,7 @@ import org.springframework.test.context.ContextConfiguration;
|
||||||
import org.springframework.test.context.junit.jupiter.SpringExtension;
|
import org.springframework.test.context.junit.jupiter.SpringExtension;
|
||||||
import org.springframework.transaction.PlatformTransactionManager;
|
import org.springframework.transaction.PlatformTransactionManager;
|
||||||
|
|
||||||
|
import static ca.uhn.fhir.jpa.term.api.ITermCodeSystemStorageSvc.MAKE_LOADING_VERSION_CURRENT;
|
||||||
import static org.junit.jupiter.api.Assertions.assertEquals;
|
import static org.junit.jupiter.api.Assertions.assertEquals;
|
||||||
import static org.junit.jupiter.api.Assertions.fail;
|
import static org.junit.jupiter.api.Assertions.fail;
|
||||||
import static org.mockito.ArgumentMatchers.anyCollection;
|
import static org.mockito.ArgumentMatchers.anyCollection;
|
||||||
|
@ -90,6 +92,13 @@ public class ValueSetExpansionR4ElasticsearchIT extends BaseJpaTest {
|
||||||
@Mock
|
@Mock
|
||||||
private IValueSetConceptAccumulator myValueSetCodeAccumulator;
|
private IValueSetConceptAccumulator myValueSetCodeAccumulator;
|
||||||
|
|
||||||
|
|
||||||
|
@BeforeEach
|
||||||
|
public void beforeEach() {
|
||||||
|
when(mySrd.getUserData().getOrDefault(MAKE_LOADING_VERSION_CURRENT, Boolean.TRUE)).thenReturn(Boolean.TRUE);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
@AfterEach
|
@AfterEach
|
||||||
public void after() {
|
public void after() {
|
||||||
myDaoConfig.setMaximumExpansionSize(DaoConfig.DEFAULT_MAX_EXPANSION_SIZE);
|
myDaoConfig.setMaximumExpansionSize(DaoConfig.DEFAULT_MAX_EXPANSION_SIZE);
|
||||||
|
|
Loading…
Reference in New Issue