Make sure a loinc CodeSystem always has a ForcedId
This commit is contained in:
parent
18e3ed68eb
commit
d372371f36
|
@ -51,7 +51,6 @@ import ca.uhn.fhir.jpa.partition.SystemRequestDetails;
|
||||||
import ca.uhn.fhir.jpa.patch.FhirPatch;
|
import ca.uhn.fhir.jpa.patch.FhirPatch;
|
||||||
import ca.uhn.fhir.jpa.patch.JsonPatchUtils;
|
import ca.uhn.fhir.jpa.patch.JsonPatchUtils;
|
||||||
import ca.uhn.fhir.jpa.patch.XmlPatchUtils;
|
import ca.uhn.fhir.jpa.patch.XmlPatchUtils;
|
||||||
import ca.uhn.fhir.jpa.search.DatabaseBackedPagingProvider;
|
|
||||||
import ca.uhn.fhir.jpa.search.PersistedJpaBundleProvider;
|
import ca.uhn.fhir.jpa.search.PersistedJpaBundleProvider;
|
||||||
import ca.uhn.fhir.jpa.search.cache.SearchCacheStatusEnum;
|
import ca.uhn.fhir.jpa.search.cache.SearchCacheStatusEnum;
|
||||||
import ca.uhn.fhir.jpa.search.reindex.IResourceReindexingSvc;
|
import ca.uhn.fhir.jpa.search.reindex.IResourceReindexingSvc;
|
||||||
|
@ -169,7 +168,7 @@ public abstract class BaseHapiFhirResourceDao<T extends IBaseResource> extends B
|
||||||
@Autowired
|
@Autowired
|
||||||
private IRequestPartitionHelperSvc myRequestPartitionHelperService;
|
private IRequestPartitionHelperSvc myRequestPartitionHelperService;
|
||||||
@Autowired
|
@Autowired
|
||||||
private HapiTransactionService myTransactionService;
|
protected HapiTransactionService myTransactionService;
|
||||||
@Autowired
|
@Autowired
|
||||||
private MatchUrlService myMatchUrlService;
|
private MatchUrlService myMatchUrlService;
|
||||||
@Autowired
|
@Autowired
|
||||||
|
@ -221,7 +220,7 @@ public abstract class BaseHapiFhirResourceDao<T extends IBaseResource> extends B
|
||||||
/**
|
/**
|
||||||
* Called for FHIR create (POST) operations
|
* Called for FHIR create (POST) operations
|
||||||
*/
|
*/
|
||||||
private DaoMethodOutcome doCreateForPost(T theResource, String theIfNoneExist, boolean thePerformIndexing, TransactionDetails theTransactionDetails, RequestDetails theRequestDetails) {
|
protected DaoMethodOutcome doCreateForPost(T theResource, String theIfNoneExist, boolean thePerformIndexing, TransactionDetails theTransactionDetails, RequestDetails theRequestDetails) {
|
||||||
if (theResource == null) {
|
if (theResource == null) {
|
||||||
String msg = getContext().getLocalizer().getMessage(BaseHapiFhirResourceDao.class, "missingBody");
|
String msg = getContext().getLocalizer().getMessage(BaseHapiFhirResourceDao.class, "missingBody");
|
||||||
throw new InvalidRequestException(msg);
|
throw new InvalidRequestException(msg);
|
||||||
|
|
|
@ -109,8 +109,10 @@ public class JpaPersistedResourceValidationSupport implements IValidationSupport
|
||||||
public IBaseResource fetchCodeSystem(String theSystem) {
|
public IBaseResource fetchCodeSystem(String theSystem) {
|
||||||
if (myTermReadSvc.isLoincNotGenericUnversionedCodeSystem(theSystem)) {
|
if (myTermReadSvc.isLoincNotGenericUnversionedCodeSystem(theSystem)) {
|
||||||
Optional<IBaseResource> currentCSOpt = getCodeSystemCurrentVersion(new UriType(theSystem));
|
Optional<IBaseResource> currentCSOpt = getCodeSystemCurrentVersion(new UriType(theSystem));
|
||||||
return currentCSOpt.orElseThrow(() -> new ResourceNotFoundException(
|
if (! currentCSOpt.isPresent()) {
|
||||||
"Couldn't find current version CodeSystem for url: " + theSystem));
|
ourLog.info("Couldn't find current version of CodeSystem: " + theSystem);
|
||||||
|
}
|
||||||
|
return currentCSOpt.orElse(null);
|
||||||
}
|
}
|
||||||
|
|
||||||
return fetchResource(myCodeSystemType, theSystem);
|
return fetchResource(myCodeSystemType, theSystem);
|
||||||
|
@ -125,7 +127,16 @@ public class JpaPersistedResourceValidationSupport implements IValidationSupport
|
||||||
|
|
||||||
IFhirResourceDao<? extends IBaseResource> valueSetResourceDao = myDaoRegistry.getResourceDao(myCodeSystemType);
|
IFhirResourceDao<? extends IBaseResource> valueSetResourceDao = myDaoRegistry.getResourceDao(myCodeSystemType);
|
||||||
String forcedId = "loinc";
|
String forcedId = "loinc";
|
||||||
IBaseResource codeSystem = valueSetResourceDao.read(new IdDt("CodeSystem", forcedId));
|
|
||||||
|
// try/catch ignores exception because we need code to fall back to other options
|
||||||
|
IBaseResource codeSystem;
|
||||||
|
try {
|
||||||
|
codeSystem = valueSetResourceDao.read(new IdDt("CodeSystem", forcedId));
|
||||||
|
|
||||||
|
} catch (Exception theE) {
|
||||||
|
return Optional.empty();
|
||||||
|
}
|
||||||
|
|
||||||
return Optional.ofNullable(codeSystem);
|
return Optional.ofNullable(codeSystem);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -25,6 +25,7 @@ import ca.uhn.fhir.context.support.IValidationSupport;
|
||||||
import ca.uhn.fhir.context.support.IValidationSupport.CodeValidationResult;
|
import ca.uhn.fhir.context.support.IValidationSupport.CodeValidationResult;
|
||||||
import ca.uhn.fhir.context.support.ValidationSupportContext;
|
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.api.model.DaoMethodOutcome;
|
||||||
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.model.entity.ResourceTable;
|
import ca.uhn.fhir.jpa.model.entity.ResourceTable;
|
||||||
|
@ -46,12 +47,14 @@ import org.hl7.fhir.r4.model.Coding;
|
||||||
import org.springframework.beans.factory.annotation.Autowired;
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
|
|
||||||
import javax.annotation.Nonnull;
|
import javax.annotation.Nonnull;
|
||||||
|
import java.security.InvalidParameterException;
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.Date;
|
import java.util.Date;
|
||||||
import java.util.List;
|
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 org.apache.commons.lang3.StringUtils.isBlank;
|
||||||
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> {
|
||||||
|
@ -173,4 +176,17 @@ public class FhirResourceDaoCodeSystemR4 extends BaseHapiFhirResourceDao<CodeSys
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public DaoMethodOutcome create(CodeSystem theResource, String theIfNoneExist, boolean thePerformIndexing,
|
||||||
|
@Nonnull TransactionDetails theTransactionDetails, RequestDetails theRequestDetails) {
|
||||||
|
// loinc CodeSystem must have an ID
|
||||||
|
if (isNotBlank(theResource.getUrl()) && theResource.getUrl().contains("loinc")
|
||||||
|
&& isBlank(theResource.getIdElement().getIdPart())) {
|
||||||
|
throw new InvalidParameterException("'loinc' CodeSystem must have an ID");
|
||||||
|
}
|
||||||
|
return myTransactionService.execute(theRequestDetails, theTransactionDetails,
|
||||||
|
tx -> doCreateForPost(theResource, theIfNoneExist, thePerformIndexing, theTransactionDetails, theRequestDetails));
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -86,6 +86,7 @@ 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.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 {
|
||||||
|
@ -139,6 +140,9 @@ public class TermCodeSystemStorageSvcImpl implements ITermCodeSystemStorageSvc {
|
||||||
CodeSystem codeSystemResource = new CodeSystem();
|
CodeSystem codeSystemResource = new CodeSystem();
|
||||||
codeSystemResource.setUrl(theSystem);
|
codeSystemResource.setUrl(theSystem);
|
||||||
codeSystemResource.setContent(CodeSystem.CodeSystemContentMode.NOTPRESENT);
|
codeSystemResource.setContent(CodeSystem.CodeSystemContentMode.NOTPRESENT);
|
||||||
|
if (isBlank(codeSystemResource.getIdElement().getIdPart()) && theSystem.contains("loinc")) {
|
||||||
|
codeSystemResource.setId("loinc");
|
||||||
|
}
|
||||||
myTerminologyVersionAdapterSvc.createOrUpdateCodeSystem(codeSystemResource);
|
myTerminologyVersionAdapterSvc.createOrUpdateCodeSystem(codeSystemResource);
|
||||||
|
|
||||||
cs = myCodeSystemDao.findByCodeSystemUri(theSystem);
|
cs = myCodeSystemDao.findByCodeSystemUri(theSystem);
|
||||||
|
|
|
@ -33,6 +33,8 @@ import org.springframework.context.ApplicationContext;
|
||||||
import org.springframework.context.event.ContextRefreshedEvent;
|
import org.springframework.context.event.ContextRefreshedEvent;
|
||||||
import org.springframework.context.event.EventListener;
|
import org.springframework.context.event.EventListener;
|
||||||
|
|
||||||
|
import java.security.InvalidParameterException;
|
||||||
|
|
||||||
import static org.apache.commons.lang3.StringUtils.isBlank;
|
import static org.apache.commons.lang3.StringUtils.isBlank;
|
||||||
|
|
||||||
public class TermVersionAdapterSvcR4 extends BaseTermVersionAdapterSvcImpl implements ITermVersionAdapterSvc {
|
public class TermVersionAdapterSvcR4 extends BaseTermVersionAdapterSvcImpl implements ITermVersionAdapterSvc {
|
||||||
|
@ -63,6 +65,9 @@ public class TermVersionAdapterSvcR4 extends BaseTermVersionAdapterSvcImpl imple
|
||||||
public IIdType createOrUpdateCodeSystem(org.hl7.fhir.r4.model.CodeSystem theCodeSystemResource, RequestDetails theRequestDetails) {
|
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())) {
|
||||||
|
if (theCodeSystemResource.getUrl().contains("loinc")) {
|
||||||
|
throw new InvalidParameterException("LOINC CodeSystem must have an 'ID' element");
|
||||||
|
}
|
||||||
String matchUrl = "CodeSystem?url=" + UrlUtil.escapeUrlParam(theCodeSystemResource.getUrl());
|
String matchUrl = "CodeSystem?url=" + UrlUtil.escapeUrlParam(theCodeSystemResource.getUrl());
|
||||||
return myCodeSystemResourceDao.update(theCodeSystemResource, matchUrl, theRequestDetails).getId();
|
return myCodeSystemResourceDao.update(theCodeSystemResource, matchUrl, theRequestDetails).getId();
|
||||||
} else {
|
} else {
|
||||||
|
|
|
@ -501,7 +501,8 @@ public class FhirResourceDaoR4ValidateTest extends BaseJpaR4Test {
|
||||||
cs.setContent(CodeSystem.CodeSystemContentMode.COMPLETE);
|
cs.setContent(CodeSystem.CodeSystemContentMode.COMPLETE);
|
||||||
cs.setUrl("http://loinc.org");
|
cs.setUrl("http://loinc.org");
|
||||||
cs.addConcept().setCode("123-4").setDisplay("Code 123 4");
|
cs.addConcept().setCode("123-4").setDisplay("Code 123 4");
|
||||||
myCodeSystemDao.create(cs);
|
cs.setId("loinc");
|
||||||
|
myCodeSystemDao.update(cs);
|
||||||
|
|
||||||
Group group = new Group();
|
Group group = new Group();
|
||||||
group.setId("ABC");
|
group.setId("ABC");
|
||||||
|
@ -567,8 +568,8 @@ public class FhirResourceDaoR4ValidateTest extends BaseJpaR4Test {
|
||||||
CodeSystem cs = new CodeSystem();
|
CodeSystem cs = new CodeSystem();
|
||||||
cs.setContent(CodeSystem.CodeSystemContentMode.COMPLETE);
|
cs.setContent(CodeSystem.CodeSystemContentMode.COMPLETE);
|
||||||
cs.setUrl("http://loinc.org");
|
cs.setUrl("http://loinc.org");
|
||||||
cs.addConcept().setCode("123-4").setDisplay("Code 123 4");
|
cs.addConcept().setCode("123-4").setDisplay("Code 123 4").setId("loinc");
|
||||||
myCodeSystemDao.create(cs);
|
myCodeSystemDao.update(cs);
|
||||||
|
|
||||||
Group group = new Group();
|
Group group = new Group();
|
||||||
group.setId("ABC");
|
group.setId("ABC");
|
||||||
|
@ -628,14 +629,15 @@ public class FhirResourceDaoR4ValidateTest extends BaseJpaR4Test {
|
||||||
|
|
||||||
ValueSet vs = new ValueSet();
|
ValueSet vs = new ValueSet();
|
||||||
vs.setUrl("http://example.com/fhir/ValueSet/observation-vitalsignresult");
|
vs.setUrl("http://example.com/fhir/ValueSet/observation-vitalsignresult");
|
||||||
vs.getCompose().addInclude().setSystem("http://loinc.org");
|
vs.getCompose().addInclude().setSystem("http://loinc.org").setId("loinc");
|
||||||
myValueSetDao.create(vs);
|
myValueSetDao.create(vs);
|
||||||
|
|
||||||
CodeSystem cs = new CodeSystem();
|
CodeSystem cs = new CodeSystem();
|
||||||
cs.setContent(CodeSystem.CodeSystemContentMode.COMPLETE);
|
cs.setContent(CodeSystem.CodeSystemContentMode.COMPLETE);
|
||||||
cs.setUrl("http://loinc.org");
|
cs.setUrl("http://loinc.org");
|
||||||
cs.addConcept().setCode("123-4").setDisplay("Code 123 4");
|
cs.addConcept().setCode("123-4").setDisplay("Code 123 4");
|
||||||
myCodeSystemDao.create(cs);
|
cs.setId("loinc");
|
||||||
|
myCodeSystemDao.update(cs);
|
||||||
|
|
||||||
Group group = new Group();
|
Group group = new Group();
|
||||||
group.setId("ABC");
|
group.setId("ABC");
|
||||||
|
@ -936,6 +938,7 @@ public class FhirResourceDaoR4ValidateTest extends BaseJpaR4Test {
|
||||||
// Valid code
|
// Valid code
|
||||||
obs.getText().setStatus(Narrative.NarrativeStatus.GENERATED);
|
obs.getText().setStatus(Narrative.NarrativeStatus.GENERATED);
|
||||||
obs.getCode().getCodingFirstRep().setSystem("http://loinc.org").setCode("CODE3").setDisplay("Display 3");
|
obs.getCode().getCodingFirstRep().setSystem("http://loinc.org").setCode("CODE3").setDisplay("Display 3");
|
||||||
|
obs.getCode().getCodingFirstRep().setId("loinc");
|
||||||
oo = validateAndReturnOutcome(obs);
|
oo = validateAndReturnOutcome(obs);
|
||||||
assertEquals("No issues detected during validation", oo.getIssueFirstRep().getDiagnostics(), encode(oo));
|
assertEquals("No issues detected during validation", oo.getIssueFirstRep().getDiagnostics(), encode(oo));
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue