More loinc work

This commit is contained in:
James Agnew 2018-03-22 07:16:16 -04:00
parent 308ac63a77
commit 45a16fe066
13 changed files with 91 additions and 76 deletions

View File

@ -5,9 +5,9 @@ import ca.uhn.fhir.context.FhirContext;
import ca.uhn.fhir.context.FhirVersionEnum;
import ca.uhn.fhir.jpa.dao.DaoConfig;
import ca.uhn.fhir.jpa.dao.IFhirSystemDao;
import ca.uhn.fhir.jpa.provider.TerminologyUploaderProvider;
import ca.uhn.fhir.jpa.provider.dstu3.JpaConformanceProviderDstu3;
import ca.uhn.fhir.jpa.provider.dstu3.JpaSystemProviderDstu3;
import ca.uhn.fhir.jpa.provider.dstu3.TerminologyUploaderProviderDstu3;
import ca.uhn.fhir.jpa.rp.dstu3.ActivityDefinitionResourceProvider;
import ca.uhn.fhir.jpa.rp.dstu3.MeasureResourceProvider;
import ca.uhn.fhir.jpa.rp.dstu3.PlanDefinitionResourceProvider;
@ -149,7 +149,7 @@ public class CdsServerExample extends RestfulServer {
* so it is a potential security vulnerability. Consider using an AuthorizationInterceptor
* with this feature.
*/
registerProvider(myAppCtx.getBean(TerminologyUploaderProviderDstu3.class));
registerProvider(myAppCtx.getBean(TerminologyUploaderProvider.class));
}
public IResourceProvider getProvider(String name) {

View File

@ -8,7 +8,6 @@ import ca.uhn.fhir.jpa.provider.JpaConformanceProviderDstu2;
import ca.uhn.fhir.jpa.provider.JpaSystemProviderDstu2;
import ca.uhn.fhir.jpa.provider.dstu3.JpaConformanceProviderDstu3;
import ca.uhn.fhir.jpa.provider.dstu3.JpaSystemProviderDstu3;
import ca.uhn.fhir.jpa.provider.dstu3.TerminologyUploaderProviderDstu3;
import ca.uhn.fhir.jpa.provider.r4.JpaConformanceProviderR4;
import ca.uhn.fhir.jpa.provider.r4.JpaSystemProviderR4;
import ca.uhn.fhir.jpa.provider.TerminologyUploaderProvider;
@ -79,7 +78,7 @@ public class JpaServerDemo extends RestfulServer {
systemProvider.add(myAppCtx.getBean("mySystemProviderDstu2", JpaSystemProviderDstu2.class));
} else if (fhirVersion == FhirVersionEnum.DSTU3) {
systemProvider.add(myAppCtx.getBean("mySystemProviderDstu3", JpaSystemProviderDstu3.class));
systemProvider.add(myAppCtx.getBean(TerminologyUploaderProviderDstu3.class));
systemProvider.add(myAppCtx.getBean(TerminologyUploaderProvider.class));
} else if (fhirVersion == FhirVersionEnum.R4) {
systemProvider.add(myAppCtx.getBean("mySystemProviderR4", JpaSystemProviderR4.class));
systemProvider.add(myAppCtx.getBean(TerminologyUploaderProvider.class));

View File

@ -188,7 +188,7 @@ public class FhirResourceDaoCodeSystemDstu3 extends FhirResourceDaoDstu3<CodeSys
if (isNotBlank(next.getCode())) {
TermConcept termConcept = new TermConcept();
termConcept.setCode(next.getCode());
termConcept.setCodeSystem(theCodeSystemVersion);
termConcept.setCodeSystemVersion(theCodeSystemVersion);
termConcept.setDisplay(next.getDisplay());
termConcept.addChildren(toPersistedConcepts(next.getConcept(), theCodeSystemVersion), RelationshipTypeEnum.ISA);
retVal.add(termConcept);

View File

@ -161,7 +161,7 @@ public class FhirResourceDaoCodeSystemR4 extends FhirResourceDaoR4<CodeSystem> i
if (isNotBlank(next.getCode())) {
TermConcept termConcept = new TermConcept();
termConcept.setCode(next.getCode());
termConcept.setCodeSystem(theCodeSystemVersion);
termConcept.setCodeSystemVersion(theCodeSystemVersion);
termConcept.setDisplay(next.getDisplay());
termConcept.addChildren(toPersistedConcepts(next.getConcept(), theCodeSystemVersion), RelationshipTypeEnum.ISA);
retVal.add(termConcept);

View File

@ -9,9 +9,9 @@ package ca.uhn.fhir.jpa.entity;
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
*
* http://www.apache.org/licenses/LICENSE-2.0
*
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
@ -20,28 +20,15 @@ package ca.uhn.fhir.jpa.entity;
* #L%
*/
import ca.uhn.fhir.util.CoverageIgnore;
import javax.persistence.*;
import java.io.Serializable;
import java.util.ArrayList;
import java.util.Collection;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.FetchType;
import javax.persistence.ForeignKey;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.JoinColumn;
import javax.persistence.OneToMany;
import javax.persistence.OneToOne;
import javax.persistence.SequenceGenerator;
import javax.persistence.Table;
import javax.persistence.UniqueConstraint;
import ca.uhn.fhir.util.CoverageIgnore;
//@formatter:off
@Table(name="TRM_CODESYSTEM_VER"
@Table(name = "TRM_CODESYSTEM_VER"
// Note, we used to have a constraint named IDX_CSV_RESOURCEPID_AND_VER (don't reuse this)
)
@Entity()
@ -54,17 +41,23 @@ public class TermCodeSystemVersion implements Serializable {
@Id()
@SequenceGenerator(name = "SEQ_CODESYSTEMVER_PID", sequenceName = "SEQ_CODESYSTEMVER_PID")
@GeneratedValue(strategy=GenerationType.AUTO, generator="SEQ_CODESYSTEMVER_PID")
@GeneratedValue(strategy = GenerationType.AUTO, generator = "SEQ_CODESYSTEMVER_PID")
@Column(name = "PID")
private Long myId;
@OneToOne()
@JoinColumn(name = "RES_ID", referencedColumnName = "RES_ID", nullable = false, updatable = false, foreignKey=@ForeignKey(name="FK_CODESYSVER_RES_ID"))
@JoinColumn(name = "RES_ID", referencedColumnName = "RES_ID", nullable = false, updatable = false, foreignKey = @ForeignKey(name = "FK_CODESYSVER_RES_ID"))
private ResourceTable myResource;
@Column(name = "CS_VERSION_ID", nullable = true, updatable = false)
private String myCodeSystemVersionId;
/**
* This was added in HAPI FHIR 3.3.0 and is nullable just to avoid migration
* issued. It should be made non-nullable at some point.
*/
@ManyToOne
@JoinColumn(name = "CODESYSTEM_PID", referencedColumnName = "PID", nullable = true)
private TermCodeSystem myCodeSystem;
@SuppressWarnings("unused")
@OneToOne(mappedBy = "myCurrentVersion", optional = true)
private TermCodeSystem myCodeSystemHavingThisVersionAsCurrentVersionIfAny;
@ -76,26 +69,6 @@ public class TermCodeSystemVersion implements Serializable {
super();
}
public Collection<TermConcept> getConcepts() {
if (myConcepts == null) {
myConcepts = new ArrayList<>();
}
return myConcepts;
}
public Long getPid() {
return myId;
}
@Override
public int hashCode() {
final int prime = 31;
int result = 1;
result = prime * result + ((myResource.getId() == null) ? 0 : myResource.getId().hashCode());
result = prime * result + ((myCodeSystemVersionId == null) ? 0 : myCodeSystemVersionId.hashCode());
return result;
}
@CoverageIgnore
@Override
public boolean equals(Object obj) {
@ -114,7 +87,7 @@ public class TermCodeSystemVersion implements Serializable {
} else if (!myResource.getId().equals(other.myResource.getId())) {
return false;
}
if (myCodeSystemVersionId == null) {
if (other.myCodeSystemVersionId != null) {
return false;
@ -125,20 +98,48 @@ public class TermCodeSystemVersion implements Serializable {
return true;
}
public ResourceTable getResource() {
return myResource;
public TermCodeSystem getCodeSystem() {
return myCodeSystem;
}
public void setCodeSystem(TermCodeSystem theCodeSystem) {
myCodeSystem = theCodeSystem;
}
public String getCodeSystemVersionId() {
return myCodeSystemVersionId;
}
public void setResource(ResourceTable theResource) {
myResource = theResource;
}
public void setCodeSystemVersionId(String theCodeSystemVersionId) {
myCodeSystemVersionId = theCodeSystemVersionId;
}
public Collection<TermConcept> getConcepts() {
if (myConcepts == null) {
myConcepts = new ArrayList<>();
}
return myConcepts;
}
public Long getPid() {
return myId;
}
public ResourceTable getResource() {
return myResource;
}
public void setResource(ResourceTable theResource) {
myResource = theResource;
}
@Override
public int hashCode() {
final int prime = 31;
int result = 1;
result = prime * result + ((myResource.getId() == null) ? 0 : myResource.getId().hashCode());
result = prime * result + ((myCodeSystemVersionId == null) ? 0 : myCodeSystemVersionId.hashCode());
return result;
}
}

View File

@ -101,7 +101,7 @@ public class TermConcept implements Serializable {
}
public TermConcept(TermCodeSystemVersion theCs, String theCode) {
setCodeSystem(theCs);
setCodeSystemVersion(theCs);
setCode(theCode);
}
@ -178,14 +178,14 @@ public class TermConcept implements Serializable {
myCode = theCode;
}
public TermCodeSystemVersion getCodeSystem() {
public TermCodeSystemVersion getCodeSystemVersion() {
return myCodeSystem;
}
public void setCodeSystem(TermCodeSystemVersion theCodeSystem) {
myCodeSystem = theCodeSystem;
if (theCodeSystem.getPid() != null) {
myCodeSystemVersionPid = theCodeSystem.getPid();
public void setCodeSystemVersion(TermCodeSystemVersion theCodeSystemVersion) {
myCodeSystem = theCodeSystemVersion;
if (theCodeSystemVersion.getPid() != null) {
myCodeSystemVersionPid = theCodeSystemVersion.getPid();
}
}

View File

@ -408,7 +408,7 @@ public abstract class BaseHapiTerminologySvcImpl implements IHapiTerminologySvc
ourLog.info("Have processed {}/{} concepts ({}%)", theConceptsStack.size(), theTotalConcepts, (int) (pct * 100.0f));
}
theConcept.setCodeSystem(theCodeSystem);
theConcept.setCodeSystemVersion(theCodeSystem);
theConcept.setIndexStatus(BaseHapiFhirDao.INDEX_STATUS_INDEXED);
if (theConceptsStack.size() <= myDaoConfig.getDeferIndexingForCodesystemsOfSize()) {
@ -436,10 +436,10 @@ public abstract class BaseHapiTerminologySvcImpl implements IHapiTerminologySvc
}
private void populateVersion(TermConcept theNext, TermCodeSystemVersion theCodeSystemVersion) {
if (theNext.getCodeSystem() != null) {
if (theNext.getCodeSystemVersion() != null) {
return;
}
theNext.setCodeSystem(theCodeSystemVersion);
theNext.setCodeSystemVersion(theCodeSystemVersion);
for (TermConceptParentChildLink next : theNext.getChildren()) {
populateVersion(next.getChild(), theCodeSystemVersion);
}
@ -667,6 +667,7 @@ public abstract class BaseHapiTerminologySvcImpl implements IHapiTerminologySvc
throw new UnprocessableEntityException(msg);
}
}
theCodeSystemVersion.setCodeSystem(codeSystem);
ourLog.info("Validating all codes in CodeSystem for storage (this can take some time for large sets)");
@ -753,8 +754,8 @@ public abstract class BaseHapiTerminologySvcImpl implements IHapiTerminologySvc
private int validateConceptForStorage(TermConcept theConcept, TermCodeSystemVersion theCodeSystem, ArrayList<String> theConceptsStack,
IdentityHashMap<TermConcept, Object> theAllConcepts) {
ValidateUtil.isTrueOrThrowInvalidRequest(theConcept.getCodeSystem() != null, "CodesystemValue is null");
ValidateUtil.isTrueOrThrowInvalidRequest(theConcept.getCodeSystem() == theCodeSystem, "CodeSystems are not equal");
ValidateUtil.isTrueOrThrowInvalidRequest(theConcept.getCodeSystemVersion() != null, "CodesystemValue is null");
ValidateUtil.isTrueOrThrowInvalidRequest(theConcept.getCodeSystemVersion() == theCodeSystem, "CodeSystems are not equal");
ValidateUtil.isNotBlankOrThrowInvalidRequest(theConcept.getCode(), "Codesystem contains a code with no code value");
if (theConceptsStack.contains(theConcept.getCode())) {

View File

@ -237,7 +237,7 @@ public class HapiTerminologySvcDstu3 extends BaseHapiTerminologySvcImpl implemen
def.setDisplay(code.getDisplay());
CodeValidationResult retVal = new CodeValidationResult(def);
retVal.setProperties(code.toValidationProperties());
retVal.setCodeSystemName(code.getCodeSystem().get);
retVal.setCodeSystemName(code.getCodeSystemVersion().getCodeSystem().getName());
return retVal;
}

View File

@ -389,7 +389,7 @@ public class TerminologyLoaderSvcImpl implements IHapiTerminologyLoaderSvc {
if (concept == null) {
concept = new TermConcept();
id2concept.put(id, concept);
concept.setCodeSystem(codeSystemVersion);
concept.setCodeSystemVersion(codeSystemVersion);
}
return concept;
}

View File

@ -39,7 +39,7 @@ public class LoincHierarchyHandler implements IRecordHandler {
TermConcept retVal = myCode2Concept.get(theCode);
if (retVal == null) {
retVal = new TermConcept();
retVal.setCodeSystem(myCodeSystemVersion);
retVal.setCodeSystemVersion(myCodeSystemVersion);
retVal.setCode(theCode);
retVal.setDisplay(theDisplay);
myCode2Concept.put(theCode, retVal);

View File

@ -5,9 +5,7 @@ import ca.uhn.fhir.jpa.dao.IFhirResourceDaoCodeSystem;
import ca.uhn.fhir.jpa.dao.dstu3.BaseJpaDstu3Test;
import ca.uhn.fhir.util.TestUtil;
import org.hl7.fhir.convertors.VersionConvertor_30_40;
import org.hl7.fhir.dstu3.model.StringType;
import org.hl7.fhir.dstu3.model.ValueSet;
import org.hl7.fhir.dstu3.model.Parameters;
import org.hl7.fhir.dstu3.model.*;
import org.junit.After;
import org.junit.AfterClass;
import org.junit.Before;
@ -16,10 +14,12 @@ import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import java.util.Optional;
import java.util.Set;
import java.util.stream.Collectors;
import static org.hamcrest.Matchers.containsInAnyOrder;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertThat;
public class TerminologyLoaderSvcIntegrationDstu3Test extends BaseJpaDstu3Test {
@ -73,6 +73,21 @@ public class TerminologyLoaderSvcIntegrationDstu3Test extends BaseJpaDstu3Test {
Parameters parameters = VersionConvertor_30_40.convertParameters(parametersR4);
ourLog.info(myFhirCtx.newXmlParser().setPrettyPrint(true).encodeResourceToString(parameters));
assertEquals("SYSTEM", this.<CodeType>getPropertyPart(parameters, "property", "code").get().getValueAsString());
assertEquals("Heart", this.<CodeType>getPropertyPart(parameters, "property", "value").get().getValueAsString());
}
private <T extends Type> Optional<T> getPropertyPart(Parameters theParameters, String thePropName, String thePart) {
return theParameters
.getParameter()
.stream()
.filter(t -> t.getName().equals(thePropName))
.flatMap(t -> t.getPart().stream())
.filter(t -> t.getName().equals(thePart))
.map(t -> (T)t.getValue())
.findFirst();
}
private Set<String> toExpandedCodes(ValueSet theExpanded) {

View File

@ -49,12 +49,12 @@ public class TerminologySvcImplDstu3Test extends BaseJpaDstu3Test {
cs.setResource(table);
TermConcept parent = new TermConcept();
parent.setCodeSystem(cs);
parent.setCodeSystemVersion(cs);
parent.setCode("parent");
cs.getConcepts().add(parent);
TermConcept child = new TermConcept();
child.setCodeSystem(cs);
child.setCodeSystemVersion(cs);
child.setCode("child");
parent.addChild(child, RelationshipTypeEnum.ISA);

View File

@ -8,7 +8,6 @@ import ca.uhn.fhir.jpa.provider.JpaConformanceProviderDstu2;
import ca.uhn.fhir.jpa.provider.JpaSystemProviderDstu2;
import ca.uhn.fhir.jpa.provider.dstu3.JpaConformanceProviderDstu3;
import ca.uhn.fhir.jpa.provider.dstu3.JpaSystemProviderDstu3;
import ca.uhn.fhir.jpa.provider.dstu3.TerminologyUploaderProviderDstu3;
import ca.uhn.fhir.jpa.provider.r4.JpaConformanceProviderR4;
import ca.uhn.fhir.jpa.provider.r4.JpaSystemProviderR4;
import ca.uhn.fhir.jpa.provider.TerminologyUploaderProvider;
@ -121,7 +120,7 @@ public class TestRestfulServer extends RestfulServer {
JpaConformanceProviderDstu3 confProvider = new JpaConformanceProviderDstu3(this, systemDao, myAppCtx.getBean(DaoConfig.class));
confProvider.setImplementationDescription(implDesc);
setServerConformanceProvider(confProvider);
plainProviders.add(myAppCtx.getBean(TerminologyUploaderProviderDstu3.class));
plainProviders.add(myAppCtx.getBean(TerminologyUploaderProvider.class));
break;
}
case "R4": {