Merge remote-tracking branch 'refs/remotes/jamesagnew/master'

This commit is contained in:
Hugo Soares 2017-01-20 11:22:21 +00:00
commit 1dd0b01e81
13 changed files with 118 additions and 42 deletions

View File

@ -119,21 +119,12 @@ public class FhirResourceDaoCodeSystemDstu3 extends FhirResourceDaoDstu3<CodeSys
system = theSystem.getValue(); system = theSystem.getValue();
} }
// CodeValidationResult validateOutcome = myJpaValidationSupport.validateCode(getContext(), system, code, null); ourLog.info("Looking up {} / {}", system, code);
//
// LookupCodeResult result = new LookupCodeResult();
// result.setSearchedForCode(code);
// result.setSearchedForSystem(system);
// result.setFound(false);
// if (validateOutcome.isOk()) {
// result.setFound(true);
// result.setCodeIsAbstract(validateOutcome.asConceptDefinition().getAbstract());
// result.setCodeDisplay(validateOutcome.asConceptDefinition().getDisplay());
// }
// return result;
if (myValidationSupport.isCodeSystemSupported(getContext(), system)) { if (myValidationSupport.isCodeSystemSupported(getContext(), system)) {
ourLog.info("Code system {} is supported", system);
CodeValidationResult result = myValidationSupport.validateCode(getContext(), system, code, null); CodeValidationResult result = myValidationSupport.validateCode(getContext(), system, code, null);
if (result != null) { if (result != null) {
if (result.isOk()) { if (result.isOk()) {

View File

@ -74,7 +74,7 @@ public abstract class BaseJpaDstu3Test extends BaseJpaTest {
protected IFhirResourceDao<CarePlan> myCarePlanDao; protected IFhirResourceDao<CarePlan> myCarePlanDao;
@Autowired @Autowired
@Qualifier("myCodeSystemDaoDstu3") @Qualifier("myCodeSystemDaoDstu3")
protected IFhirResourceDao<CodeSystem> myCodeSystemDao; protected IFhirResourceDaoCodeSystem<CodeSystem, Coding, CodeableConcept> myCodeSystemDao;
@Autowired @Autowired
@Qualifier("myCompartmentDefinitionDaoDstu3") @Qualifier("myCompartmentDefinitionDaoDstu3")
protected IFhirResourceDao<CompartmentDefinition> myCompartmentDefinitionDao; protected IFhirResourceDao<CompartmentDefinition> myCompartmentDefinitionDao;

View File

@ -11,15 +11,11 @@ import java.util.ArrayList;
import java.util.List; import java.util.List;
import java.util.Set; import java.util.Set;
import org.hl7.fhir.dstu3.model.AllergyIntolerance; import org.hl7.fhir.dstu3.model.*;
import org.hl7.fhir.dstu3.model.AllergyIntolerance.AllergyIntoleranceCategory; import org.hl7.fhir.dstu3.model.AllergyIntolerance.AllergyIntoleranceCategory;
import org.hl7.fhir.dstu3.model.AllergyIntolerance.AllergyIntoleranceClinicalStatus; import org.hl7.fhir.dstu3.model.AllergyIntolerance.AllergyIntoleranceClinicalStatus;
import org.hl7.fhir.dstu3.model.AuditEvent;
import org.hl7.fhir.dstu3.model.CodeSystem;
import org.hl7.fhir.dstu3.model.CodeSystem.CodeSystemContentMode; import org.hl7.fhir.dstu3.model.CodeSystem.CodeSystemContentMode;
import org.hl7.fhir.dstu3.model.CodeSystem.ConceptDefinitionComponent; import org.hl7.fhir.dstu3.model.CodeSystem.ConceptDefinitionComponent;
import org.hl7.fhir.dstu3.model.Observation;
import org.hl7.fhir.dstu3.model.ValueSet;
import org.hl7.fhir.dstu3.model.ValueSet.ConceptSetComponent; import org.hl7.fhir.dstu3.model.ValueSet.ConceptSetComponent;
import org.hl7.fhir.dstu3.model.ValueSet.FilterOperator; import org.hl7.fhir.dstu3.model.ValueSet.FilterOperator;
import org.hl7.fhir.dstu3.model.ValueSet.ValueSetComposeComponent; import org.hl7.fhir.dstu3.model.ValueSet.ValueSetComposeComponent;
@ -32,6 +28,7 @@ import org.junit.Ignore;
import org.junit.Test; import org.junit.Test;
import ca.uhn.fhir.jpa.dao.DaoConfig; import ca.uhn.fhir.jpa.dao.DaoConfig;
import ca.uhn.fhir.jpa.dao.IFhirResourceDaoCodeSystem.LookupCodeResult;
import ca.uhn.fhir.jpa.dao.SearchParameterMap; import ca.uhn.fhir.jpa.dao.SearchParameterMap;
import ca.uhn.fhir.jpa.entity.ResourceTable; import ca.uhn.fhir.jpa.entity.ResourceTable;
import ca.uhn.fhir.jpa.entity.TermCodeSystemVersion; import ca.uhn.fhir.jpa.entity.TermCodeSystemVersion;
@ -159,6 +156,28 @@ public class FhirResourceDaoDstu3TerminologyTest extends BaseJpaDstu3Test {
} }
} }
@Test
public void testLookupSnomed() {
CodeSystem codeSystem = new CodeSystem();
codeSystem.setUrl("http://snomed.info/sct");
codeSystem.setContent(CodeSystemContentMode.NOTPRESENT);
IIdType id = myCodeSystemDao.create(codeSystem, mySrd).getId().toUnqualified();
ResourceTable table = myResourceTableDao.findOne(id.getIdPartAsLong());
TermCodeSystemVersion cs = new TermCodeSystemVersion();
cs.setResource(table);
cs.setResourceVersionId(table.getVersion());
TermConcept parentA = new TermConcept(cs, "ParentA").setDisplay("Parent A");
cs.getConcepts().add(parentA);
myTermSvc.storeNewCodeSystemVersion(table.getId(), "http://snomed.info/sct", cs);
StringType code = new StringType("ParentA");
StringType system = new StringType("http://snomed.info/sct");
LookupCodeResult outcome = myCodeSystemDao.lookupCode(code, system, null, mySrd);
assertEquals(true, outcome.isFound());
}
@Test @Test
public void testCodeSystemWithDefinedCodes() { public void testCodeSystemWithDefinedCodes() {
//@formatter:off //@formatter:off

View File

@ -23,6 +23,7 @@ import org.junit.Before;
import org.junit.Test; import org.junit.Test;
import org.springframework.transaction.annotation.Transactional; import org.springframework.transaction.annotation.Transactional;
import ca.uhn.fhir.jpa.dao.dstu3.FhirResourceDaoDstu3TerminologyTest;
import ca.uhn.fhir.rest.server.exceptions.InvalidRequestException; import ca.uhn.fhir.rest.server.exceptions.InvalidRequestException;
import ca.uhn.fhir.rest.server.exceptions.ResourceNotFoundException; import ca.uhn.fhir.rest.server.exceptions.ResourceNotFoundException;
import ca.uhn.fhir.util.TestUtil; import ca.uhn.fhir.util.TestUtil;
@ -48,10 +49,52 @@ public class ResourceProviderDstu3CodeSystemTest extends BaseResourceProviderDst
myExtensionalVsId = myValueSetDao.create(upload, mySrd).getId().toUnqualifiedVersionless(); myExtensionalVsId = myValueSetDao.create(upload, mySrd).getId().toUnqualifiedVersionless();
} }
@Test
public void testLookupOnExternalCode() {
ResourceProviderDstu3ValueSetTest.createExternalCs(myCodeSystemDao, myResourceTableDao, myTermSvc, mySrd);
Parameters respParam = ourClient
.operation()
.onType(CodeSystem.class)
.named("lookup")
.withParameter(Parameters.class, "code", new CodeType("ParentA"))
.andParameter("system", new UriType(FhirResourceDaoDstu3TerminologyTest.URL_MY_CODE_SYSTEM))
.execute();
String resp = myFhirCtx.newXmlParser().setPrettyPrint(true).encodeResourceToString(respParam);
ourLog.info(resp);
assertEquals("name", respParam.getParameter().get(0).getName());
assertEquals(("Unknown"), ((StringType)respParam.getParameter().get(0).getValue()).getValue());
assertEquals("display", respParam.getParameter().get(1).getName());
assertEquals("Parent A", ((StringType)respParam.getParameter().get(1).getValue()).getValue());
assertEquals("abstract", respParam.getParameter().get(2).getName());
assertEquals(false, ((BooleanType)respParam.getParameter().get(2).getValue()).getValue().booleanValue());
// With HTTP GET
respParam = ourClient
.operation()
.onType(CodeSystem.class)
.named("lookup")
.withParameter(Parameters.class, "code", new CodeType("ParentA"))
.andParameter("system", new UriType(FhirResourceDaoDstu3TerminologyTest.URL_MY_CODE_SYSTEM))
.useHttpGet()
.execute();
resp = myFhirCtx.newXmlParser().setPrettyPrint(true).encodeResourceToString(respParam);
ourLog.info(resp);
assertEquals("name", respParam.getParameter().get(0).getName());
assertEquals(("Unknown"), ((StringType)respParam.getParameter().get(0).getValue()).getValue());
assertEquals("display", respParam.getParameter().get(1).getName());
assertEquals("Parent A", ((StringType)respParam.getParameter().get(1).getValue()).getValue());
assertEquals("abstract", respParam.getParameter().get(2).getName());
assertEquals(false, ((BooleanType)respParam.getParameter().get(2).getValue()).getValue().booleanValue());
}
@Test @Test
public void testLookupOperationByCodeAndSystemBuiltInCode() { public void testLookupOperationByCodeAndSystemBuiltInCode() {
//@formatter:off
Parameters respParam = ourClient Parameters respParam = ourClient
.operation() .operation()
.onType(CodeSystem.class) .onType(CodeSystem.class)
@ -59,7 +102,6 @@ public class ResourceProviderDstu3CodeSystemTest extends BaseResourceProviderDst
.withParameter(Parameters.class, "code", new CodeType("ACSN")) .withParameter(Parameters.class, "code", new CodeType("ACSN"))
.andParameter("system", new UriType("http://hl7.org/fhir/v2/0203")) .andParameter("system", new UriType("http://hl7.org/fhir/v2/0203"))
.execute(); .execute();
//@formatter:on
String resp = myFhirCtx.newXmlParser().setPrettyPrint(true).encodeResourceToString(respParam); String resp = myFhirCtx.newXmlParser().setPrettyPrint(true).encodeResourceToString(respParam);
ourLog.info(resp); ourLog.info(resp);

View File

@ -1,6 +1,7 @@
package ca.uhn.fhir.jpa.provider.dstu3; package ca.uhn.fhir.jpa.provider.dstu3;
import static ca.uhn.fhir.jpa.dao.dstu3.FhirResourceDaoDstu3TerminologyTest.*; import static ca.uhn.fhir.jpa.dao.dstu3.FhirResourceDaoDstu3TerminologyTest.URL_MY_CODE_SYSTEM;
import static ca.uhn.fhir.jpa.dao.dstu3.FhirResourceDaoDstu3TerminologyTest.URL_MY_VALUE_SET;
import static org.hamcrest.Matchers.containsString; import static org.hamcrest.Matchers.containsString;
import static org.hamcrest.Matchers.containsStringIgnoringCase; import static org.hamcrest.Matchers.containsStringIgnoringCase;
import static org.hamcrest.Matchers.not; import static org.hamcrest.Matchers.not;
@ -18,30 +19,27 @@ import org.apache.http.client.methods.CloseableHttpResponse;
import org.apache.http.client.methods.HttpPost; import org.apache.http.client.methods.HttpPost;
import org.apache.http.entity.ContentType; import org.apache.http.entity.ContentType;
import org.apache.http.entity.StringEntity; import org.apache.http.entity.StringEntity;
import org.hl7.fhir.dstu3.model.BooleanType; import org.hl7.fhir.dstu3.model.*;
import org.hl7.fhir.dstu3.model.CodeSystem;
import org.hl7.fhir.dstu3.model.CodeType;
import org.hl7.fhir.dstu3.model.Parameters;
import org.hl7.fhir.dstu3.model.StringType;
import org.hl7.fhir.dstu3.model.UriType;
import org.hl7.fhir.dstu3.model.ValueSet;
import org.hl7.fhir.dstu3.model.ValueSet.ConceptSetComponent;
import org.hl7.fhir.dstu3.model.ValueSet.FilterOperator;
import org.hl7.fhir.dstu3.model.CodeSystem.CodeSystemContentMode; import org.hl7.fhir.dstu3.model.CodeSystem.CodeSystemContentMode;
import org.hl7.fhir.dstu3.model.CodeSystem.ConceptDefinitionComponent; import org.hl7.fhir.dstu3.model.CodeSystem.ConceptDefinitionComponent;
import org.hl7.fhir.dstu3.model.ValueSet.ConceptSetComponent;
import org.hl7.fhir.dstu3.model.ValueSet.FilterOperator;
import org.hl7.fhir.instance.model.api.IIdType; import org.hl7.fhir.instance.model.api.IIdType;
import org.junit.AfterClass; import org.junit.AfterClass;
import org.junit.Before; import org.junit.Before;
import org.junit.Ignore;
import org.junit.Test; import org.junit.Test;
import org.springframework.transaction.annotation.Transactional; import org.springframework.transaction.annotation.Transactional;
import ca.uhn.fhir.jpa.dao.IFhirResourceDao;
import ca.uhn.fhir.jpa.dao.data.IResourceTableDao;
import ca.uhn.fhir.jpa.entity.ResourceTable; import ca.uhn.fhir.jpa.entity.ResourceTable;
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;
import ca.uhn.fhir.jpa.entity.TermConceptParentChildLink.RelationshipTypeEnum; import ca.uhn.fhir.jpa.entity.TermConceptParentChildLink.RelationshipTypeEnum;
import ca.uhn.fhir.jpa.term.IHapiTerminologySvc;
import ca.uhn.fhir.rest.server.Constants; import ca.uhn.fhir.rest.server.Constants;
import ca.uhn.fhir.rest.server.exceptions.InvalidRequestException; import ca.uhn.fhir.rest.server.exceptions.InvalidRequestException;
import ca.uhn.fhir.rest.server.servlet.ServletRequestDetails;
import ca.uhn.fhir.util.TestUtil; import ca.uhn.fhir.util.TestUtil;
public class ResourceProviderDstu3ValueSetTest extends BaseResourceProviderDstu3Test { public class ResourceProviderDstu3ValueSetTest extends BaseResourceProviderDstu3Test {
@ -87,12 +85,20 @@ public class ResourceProviderDstu3ValueSetTest extends BaseResourceProviderDstu3
} }
private CodeSystem createExternalCs() { private CodeSystem createExternalCs() {
IFhirResourceDao<CodeSystem> codeSystemDao = myCodeSystemDao;
IResourceTableDao resourceTableDao = myResourceTableDao;
IHapiTerminologySvc termSvc = myTermSvc;
return createExternalCs(codeSystemDao, resourceTableDao, termSvc, mySrd);
}
public static CodeSystem createExternalCs(IFhirResourceDao<CodeSystem> theCodeSystemDao, IResourceTableDao theResourceTableDao, IHapiTerminologySvc theTermSvc, ServletRequestDetails theRequestDetails) {
CodeSystem codeSystem = new CodeSystem(); CodeSystem codeSystem = new CodeSystem();
codeSystem.setUrl(URL_MY_CODE_SYSTEM); codeSystem.setUrl(URL_MY_CODE_SYSTEM);
codeSystem.setContent(CodeSystemContentMode.NOTPRESENT); codeSystem.setContent(CodeSystemContentMode.NOTPRESENT);
IIdType id = myCodeSystemDao.create(codeSystem, mySrd).getId().toUnqualified(); IIdType id = theCodeSystemDao.create(codeSystem, theRequestDetails).getId().toUnqualified();
ResourceTable table = myResourceTableDao.findOne(id.getIdPartAsLong()); ResourceTable table = theResourceTableDao.findOne(id.getIdPartAsLong());
TermCodeSystemVersion cs = new TermCodeSystemVersion(); TermCodeSystemVersion cs = new TermCodeSystemVersion();
cs.setResource(table); cs.setResource(table);
@ -116,7 +122,7 @@ public class ResourceProviderDstu3ValueSetTest extends BaseResourceProviderDstu3
TermConcept parentB = new TermConcept(cs, "ParentB").setDisplay("Parent B"); TermConcept parentB = new TermConcept(cs, "ParentB").setDisplay("Parent B");
cs.getConcepts().add(parentB); cs.getConcepts().add(parentB);
myTermSvc.storeNewCodeSystemVersion(table.getId(), URL_MY_CODE_SYSTEM, cs); theTermSvc.storeNewCodeSystemVersion(table.getId(), URL_MY_CODE_SYSTEM, cs);
return codeSystem; return codeSystem;
} }

View File

@ -0,0 +1,8 @@
package ca.uhn.fhirtest.config;
import org.springframework.context.annotation.Configuration;
@Configuration
public class DbServerConfig {
}

View File

@ -68,7 +68,6 @@ public class TdlDstu2Config extends BaseJavaConfigDstu2 {
} }
@Bean(name = "myPersistenceDataSourceDstu1", destroyMethod = "close") @Bean(name = "myPersistenceDataSourceDstu1", destroyMethod = "close")
@DependsOn("dbServer")
public DataSource dataSource() { public DataSource dataSource() {
BasicDataSource retVal = new BasicDataSource(); BasicDataSource retVal = new BasicDataSource();
// retVal.setDriver(new org.apache.derby.jdbc.ClientDriver()); // retVal.setDriver(new org.apache.derby.jdbc.ClientDriver());

View File

@ -65,7 +65,6 @@ public class TdlDstu3Config extends BaseJavaConfigDstu3 {
} }
@Bean(name = "myPersistenceDataSourceDstu3", destroyMethod = "close") @Bean(name = "myPersistenceDataSourceDstu3", destroyMethod = "close")
@DependsOn("dbServer")
public DataSource dataSource() { public DataSource dataSource() {
BasicDataSource retVal = new BasicDataSource(); BasicDataSource retVal = new BasicDataSource();
// retVal.setDriver(new org.apache.derby.jdbc.ClientDriver()); // retVal.setDriver(new org.apache.derby.jdbc.ClientDriver());

View File

@ -70,7 +70,6 @@ public class TestDstu2Config extends BaseJavaConfigDstu2 {
} }
@Bean(name = "myPersistenceDataSourceDstu1", destroyMethod = "close") @Bean(name = "myPersistenceDataSourceDstu1", destroyMethod = "close")
@DependsOn("dbServer")
public DataSource dataSource() { public DataSource dataSource() {
BasicDataSource retVal = new BasicDataSource(); BasicDataSource retVal = new BasicDataSource();
retVal.setDriver(new org.postgresql.Driver()); retVal.setDriver(new org.postgresql.Driver());

View File

@ -74,7 +74,6 @@ public class TestDstu3Config extends BaseJavaConfigDstu3 {
} }
@Bean(name = "myPersistenceDataSourceDstu3", destroyMethod = "close") @Bean(name = "myPersistenceDataSourceDstu3", destroyMethod = "close")
@DependsOn("dbServer")
public DataSource dataSource() { public DataSource dataSource() {
BasicDataSource retVal = new BasicDataSource(); BasicDataSource retVal = new BasicDataSource();
retVal.setDriver(new org.postgresql.Driver()); retVal.setDriver(new org.postgresql.Driver());

View File

@ -10,6 +10,7 @@ import org.apache.commons.io.Charsets;
import org.apache.commons.lang3.Validate; import org.apache.commons.lang3.Validate;
import org.hl7.fhir.dstu3.model.*; import org.hl7.fhir.dstu3.model.*;
import org.hl7.fhir.dstu3.model.Bundle.BundleEntryComponent; import org.hl7.fhir.dstu3.model.Bundle.BundleEntryComponent;
import org.hl7.fhir.dstu3.model.CodeSystem.CodeSystemContentMode;
import org.hl7.fhir.dstu3.model.CodeSystem.ConceptDefinitionComponent; import org.hl7.fhir.dstu3.model.CodeSystem.ConceptDefinitionComponent;
import org.hl7.fhir.dstu3.model.OperationOutcome.IssueSeverity; import org.hl7.fhir.dstu3.model.OperationOutcome.IssueSeverity;
import org.hl7.fhir.dstu3.model.ValueSet.ConceptReferenceComponent; import org.hl7.fhir.dstu3.model.ValueSet.ConceptReferenceComponent;
@ -142,7 +143,7 @@ public class DefaultProfileValidationSupport implements IValidationSupport {
@Override @Override
public boolean isCodeSystemSupported(FhirContext theContext, String theSystem) { public boolean isCodeSystemSupported(FhirContext theContext, String theSystem) {
CodeSystem cs = fetchCodeSystem(theContext, theSystem); CodeSystem cs = fetchCodeSystem(theContext, theSystem);
return cs != null; return cs != null && cs.getContent() != CodeSystemContentMode.NOTPRESENT;
} }
private void loadCodeSystems(FhirContext theContext, Map<String, CodeSystem> theCodeSystems, Map<String, ValueSet> theValueSets, String theClasspath) { private void loadCodeSystems(FhirContext theContext, Map<String, CodeSystem> theCodeSystems, Map<String, ValueSet> theValueSets, String theClasspath) {

View File

@ -17,6 +17,8 @@ import ca.uhn.fhir.context.FhirContext;
public class ValidationSupportChain implements IValidationSupport { public class ValidationSupportChain implements IValidationSupport {
private static final org.slf4j.Logger ourLog = org.slf4j.LoggerFactory.getLogger(ValidationSupportChain.class);
private List<IValidationSupport> myChain; private List<IValidationSupport> myChain;
/** /**
@ -97,9 +99,16 @@ public class ValidationSupportChain implements IValidationSupport {
@Override @Override
public CodeValidationResult validateCode(FhirContext theCtx, String theCodeSystem, String theCode, String theDisplay) { public CodeValidationResult validateCode(FhirContext theCtx, String theCodeSystem, String theCode, String theDisplay) {
ourLog.info("Validating code {} in chain with {} items", theCode, myChain.size());
for (IValidationSupport next : myChain) { for (IValidationSupport next : myChain) {
if (next.isCodeSystemSupported(theCtx, theCodeSystem)) { if (next.isCodeSystemSupported(theCtx, theCodeSystem)) {
return next.validateCode(theCtx, theCodeSystem, theCode, theDisplay); CodeValidationResult result = next.validateCode(theCtx, theCodeSystem, theCode, theDisplay);
ourLog.info("Chain item {} returned outcome {}", next, result.isOk());
return result;
} else {
ourLog.info("Chain item {} does not support code system {}", next, theCodeSystem);
} }
} }
return myChain.get(0).validateCode(theCtx, theCodeSystem, theCode, theDisplay); return myChain.get(0).validateCode(theCtx, theCodeSystem, theCode, theDisplay);

View File

@ -213,6 +213,10 @@
Server AuthorizationInterceptor always rejects history operation Server AuthorizationInterceptor always rejects history operation
at the type level even if rules should allow it. at the type level even if rules should allow it.
</action> </action>
<action type="fix">
JPA server terminology service was not correctly validating or expanding codes
in SNOMED CT or LOINC code systems. Thanks to David Hay for reporting!
</action>
</release> </release>
<release version="2.1" date="2016-11-11"> <release version="2.1" date="2016-11-11">
<action type="add"> <action type="add">