Handle canonical questionnaire refs in validator (#1544)

* Handle canonical questionnaire refs in validator

* FIx changelog

* Fix canonical reference

* Build tweak

* Change to trigger a build
This commit is contained in:
James Agnew 2019-10-15 20:27:53 -04:00 committed by GitHub
parent 1618ccc14c
commit 8b2ab51bc6
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
11 changed files with 267 additions and 377 deletions

View File

@ -58,3 +58,5 @@ jobs:
#checkStyleRunAnalysis: false # Optional
#pmdRunAnalysis: false # Optional
#findBugsRunAnalysis: false # Optional

View File

@ -1,22 +1,14 @@
package ca.uhn.fhir.jpa.dao.dstu3;
import ca.uhn.fhir.context.FhirContext;
import ca.uhn.fhir.jpa.dao.IFhirResourceDao;
import ca.uhn.fhir.jpa.searchparam.SearchParameterMap;
import ca.uhn.fhir.rest.api.server.IBundleProvider;
import ca.uhn.fhir.rest.param.StringParam;
import ca.uhn.fhir.rest.param.UriParam;
import org.hl7.fhir.dstu3.model.*;
import ca.uhn.fhir.jpa.dao.r4.BaseJpaValidationSupport;
import org.hl7.fhir.dstu3.model.CodeSystem;
import org.hl7.fhir.dstu3.model.StructureDefinition;
import org.hl7.fhir.dstu3.model.ValueSet;
import org.hl7.fhir.dstu3.model.ValueSet.ConceptSetComponent;
import org.hl7.fhir.dstu3.model.ValueSet.ValueSetExpansionComponent;
import org.hl7.fhir.instance.model.api.IAnyResource;
import org.hl7.fhir.instance.model.api.IBaseResource;
import org.springframework.beans.BeansException;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.ApplicationContext;
import org.springframework.context.ApplicationContextAware;
import javax.annotation.PostConstruct;
import javax.transaction.Transactional;
import javax.transaction.Transactional.TxType;
import java.util.Collections;
@ -45,18 +37,7 @@ import static org.apache.commons.lang3.StringUtils.isBlank;
*/
@Transactional(value = TxType.REQUIRED)
public class JpaValidationSupportDstu3 implements IJpaValidationSupportDstu3, ApplicationContextAware {
private static final org.slf4j.Logger ourLog = org.slf4j.LoggerFactory.getLogger(JpaValidationSupportDstu3.class);
private IFhirResourceDao<StructureDefinition> myStructureDefinitionDao;
private IFhirResourceDao<ValueSet> myValueSetDao;
private IFhirResourceDao<Questionnaire> myQuestionnaireDao;
private IFhirResourceDao<CodeSystem> myCodeSystemDao;
private IFhirResourceDao<ImplementationGuide> myImplementationGuideDao;
@Autowired
private FhirContext myDstu3Ctx;
private ApplicationContext myApplicationContext;
public class JpaValidationSupportDstu3 extends BaseJpaValidationSupport implements IJpaValidationSupportDstu3 {
/**
* Constructor
@ -98,76 +79,6 @@ public class JpaValidationSupportDstu3 implements IJpaValidationSupportDstu3, Ap
return fetchResource(theCtx, ValueSet.class, theSystem);
}
@SuppressWarnings("unchecked")
@Override
public <T extends IBaseResource> T fetchResource(FhirContext theContext, Class<T> theClass, String theUri) {
IdType id = new IdType(theUri);
boolean localReference = false;
if (id.hasBaseUrl() == false && id.hasIdPart() == true) {
localReference = true;
}
String resourceName = myDstu3Ctx.getResourceDefinition(theClass).getName();
IBundleProvider search;
if ("ValueSet".equals(resourceName)) {
if (localReference) {
SearchParameterMap params = new SearchParameterMap();
params.setLoadSynchronousUpTo(1);
params.add(IAnyResource.SP_RES_ID, new StringParam(theUri));
search = myValueSetDao.search(params);
if (search.size() == 0) {
params = new SearchParameterMap();
params.setLoadSynchronousUpTo(1);
params.add(ValueSet.SP_URL, new UriParam(theUri));
search = myValueSetDao.search(params);
}
} else {
SearchParameterMap params = new SearchParameterMap();
params.setLoadSynchronousUpTo(1);
params.add(ValueSet.SP_URL, new UriParam(theUri));
search = myValueSetDao.search(params);
}
} else if ("StructureDefinition".equals(resourceName)) {
if (theUri.startsWith("http://hl7.org/fhir/StructureDefinition/")) {
// Don't allow the core FHIR definitions to be overwritten
String typeName = theUri.substring("http://hl7.org/fhir/StructureDefinition/".length());
if (myDstu3Ctx.getElementDefinition(typeName) != null) {
return null;
}
}
SearchParameterMap params = new SearchParameterMap();
params.setLoadSynchronousUpTo(1);
params.add(StructureDefinition.SP_URL, new UriParam(theUri));
search = myStructureDefinitionDao.search(params);
} else if ("Questionnaire".equals(resourceName)) {
SearchParameterMap params = new SearchParameterMap();
params.setLoadSynchronousUpTo(1);
params.add(IAnyResource.SP_RES_ID, new StringParam(id.getIdPart()));
search = myQuestionnaireDao.search(params);
} else if ("CodeSystem".equals(resourceName)) {
SearchParameterMap params = new SearchParameterMap();
params.setLoadSynchronousUpTo(1);
params.add(CodeSystem.SP_URL, new UriParam(theUri));
search = myCodeSystemDao.search(params);
} else if ("ImplementationGuide".equals(resourceName)) {
SearchParameterMap params = new SearchParameterMap();
params.setLoadSynchronousUpTo(1);
params.add(ImplementationGuide.SP_URL, new UriParam(theUri));
search = myImplementationGuideDao.search(params);
} else {
throw new IllegalArgumentException("Can't fetch resource type: " + resourceName);
}
if (search.size() == 0) {
return null;
}
if (search.size() > 1) {
ourLog.warn("Found multiple {} instances with URL search value of: {}", resourceName, theUri);
}
return (T) search.getResources(0, 1).get(0);
}
@Override
public StructureDefinition fetchStructureDefinition(FhirContext theCtx, String theUrl) {
@ -180,20 +91,6 @@ public class JpaValidationSupportDstu3 implements IJpaValidationSupportDstu3, Ap
return false;
}
@Override
public void setApplicationContext(ApplicationContext theApplicationContext) throws BeansException {
myApplicationContext = theApplicationContext;
}
@PostConstruct
public void start() {
myStructureDefinitionDao = myApplicationContext.getBean("myStructureDefinitionDaoDstu3", IFhirResourceDao.class);
myValueSetDao = myApplicationContext.getBean("myValueSetDaoDstu3", IFhirResourceDao.class);
myQuestionnaireDao = myApplicationContext.getBean("myQuestionnaireDaoDstu3", IFhirResourceDao.class);
myCodeSystemDao = myApplicationContext.getBean("myCodeSystemDaoDstu3", IFhirResourceDao.class);
myImplementationGuideDao = myApplicationContext.getBean("myImplementationGuideDaoDstu3", IFhirResourceDao.class);
}
@Override
@Transactional(value = TxType.SUPPORTS)
public CodeValidationResult validateCode(FhirContext theCtx, String theCodeSystem, String theCode, String theDisplay) {

View File

@ -0,0 +1,118 @@
package ca.uhn.fhir.jpa.dao.r4;
import ca.uhn.fhir.context.FhirContext;
import ca.uhn.fhir.jpa.dao.DaoRegistry;
import ca.uhn.fhir.jpa.dao.IFhirResourceDao;
import ca.uhn.fhir.jpa.searchparam.SearchParameterMap;
import ca.uhn.fhir.rest.api.server.IBundleProvider;
import ca.uhn.fhir.rest.param.StringParam;
import ca.uhn.fhir.rest.param.UriParam;
import org.hl7.fhir.instance.model.api.IAnyResource;
import org.hl7.fhir.instance.model.api.IBaseResource;
import org.hl7.fhir.r4.model.*;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import javax.annotation.PostConstruct;
public abstract class BaseJpaValidationSupport {
private static final Logger ourLog = LoggerFactory.getLogger(BaseJpaValidationSupport.class);
@Autowired
private FhirContext myR4Ctx;
@Autowired
private DaoRegistry myDaoRegistry;
private IFhirResourceDao<?> myStructureDefinitionDao;
private IFhirResourceDao<?> myValueSetDao;
private IFhirResourceDao<?> myQuestionnaireDao;
private IFhirResourceDao<?> myCodeSystemDao;
private IFhirResourceDao<?> myImplementationGuideDao;
@SuppressWarnings({"unchecked", "unused"})
public <T extends IBaseResource> T fetchResource(FhirContext theContext, Class<T> theClass, String theUri) {
IdType id = new IdType(theUri);
boolean localReference = false;
if (id.hasBaseUrl() == false && id.hasIdPart() == true) {
localReference = true;
}
String resourceName = myR4Ctx.getResourceDefinition(theClass).getName();
IBundleProvider search;
if ("ValueSet".equals(resourceName)) {
if (localReference) {
SearchParameterMap params = new SearchParameterMap();
params.setLoadSynchronousUpTo(1);
params.add(IAnyResource.SP_RES_ID, new StringParam(theUri));
search = myValueSetDao.search(params);
if (search.size() == 0) {
params = new SearchParameterMap();
params.setLoadSynchronousUpTo(1);
params.add(ValueSet.SP_URL, new UriParam(theUri));
search = myValueSetDao.search(params);
}
} else {
SearchParameterMap params = new SearchParameterMap();
params.setLoadSynchronousUpTo(1);
params.add(ValueSet.SP_URL, new UriParam(theUri));
search = myValueSetDao.search(params);
}
} else if ("StructureDefinition".equals(resourceName)) {
// Don't allow the core FHIR definitions to be overwritten
if (theUri.startsWith("http://hl7.org/fhir/StructureDefinition/")) {
String typeName = theUri.substring("http://hl7.org/fhir/StructureDefinition/".length());
if (myR4Ctx.getElementDefinition(typeName) != null) {
return null;
}
}
SearchParameterMap params = new SearchParameterMap();
params.setLoadSynchronousUpTo(1);
params.add(StructureDefinition.SP_URL, new UriParam(theUri));
search = myStructureDefinitionDao.search(params);
} else if ("Questionnaire".equals(resourceName)) {
SearchParameterMap params = new SearchParameterMap();
params.setLoadSynchronousUpTo(1);
if (localReference) {
params.add(IAnyResource.SP_RES_ID, new StringParam(id.getIdPart()));
} else {
params.add(Questionnaire.SP_URL, new UriParam(id.getValue()));
}
search = myQuestionnaireDao.search(params);
} else if ("CodeSystem".equals(resourceName)) {
SearchParameterMap params = new SearchParameterMap();
params.setLoadSynchronousUpTo(1);
params.add(CodeSystem.SP_URL, new UriParam(theUri));
search = myCodeSystemDao.search(params);
} else if ("ImplementationGuide".equals(resourceName)) {
SearchParameterMap params = new SearchParameterMap();
params.setLoadSynchronousUpTo(1);
params.add(ImplementationGuide.SP_URL, new UriParam(theUri));
search = myImplementationGuideDao.search(params);
} else {
throw new IllegalArgumentException("Can't fetch resource type: " + resourceName);
}
Integer size = search.size();
if (size == null || size == 0) {
return null;
}
if (size > 1) {
ourLog.warn("Found multiple {} instances with URL search value of: {}", resourceName, theUri);
}
return (T) search.getResources(0, 1).get(0);
}
@PostConstruct
public void start() {
myStructureDefinitionDao = myDaoRegistry.getResourceDao("StructureDefinition");
myValueSetDao = myDaoRegistry.getResourceDao("ValueSet");
myQuestionnaireDao = myDaoRegistry.getResourceDao("Questionnaire");
myCodeSystemDao = myDaoRegistry.getResourceDao("CodeSystem");
myImplementationGuideDao = myDaoRegistry.getResourceDao("ImplementationGuide");
}
}

View File

@ -1,22 +1,14 @@
package ca.uhn.fhir.jpa.dao.r4;
import ca.uhn.fhir.context.*;
import ca.uhn.fhir.jpa.dao.IFhirResourceDao;
import ca.uhn.fhir.jpa.searchparam.SearchParameterMap;
import ca.uhn.fhir.rest.api.server.IBundleProvider;
import ca.uhn.fhir.rest.param.StringParam;
import ca.uhn.fhir.rest.param.UriParam;
import org.hl7.fhir.instance.model.api.IAnyResource;
import ca.uhn.fhir.context.FhirContext;
import org.hl7.fhir.instance.model.api.IBaseResource;
import org.hl7.fhir.r4.model.*;
import org.hl7.fhir.r4.hapi.ctx.IValidationSupport;
import org.hl7.fhir.r4.model.CodeSystem;
import org.hl7.fhir.r4.model.StructureDefinition;
import org.hl7.fhir.r4.model.ValueSet;
import org.hl7.fhir.r4.model.ValueSet.ConceptSetComponent;
import org.hl7.fhir.r4.terminologies.ValueSetExpander;
import org.springframework.beans.BeansException;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.ApplicationContext;
import org.springframework.context.ApplicationContextAware;
import javax.annotation.PostConstruct;
import javax.transaction.Transactional;
import javax.transaction.Transactional.TxType;
import java.util.Collections;
@ -43,19 +35,7 @@ import java.util.List;
*/
@Transactional(value = TxType.REQUIRED)
public class JpaValidationSupportR4 implements IJpaValidationSupportR4, ApplicationContextAware {
private static final org.slf4j.Logger ourLog = org.slf4j.LoggerFactory.getLogger(JpaValidationSupportR4.class);
private IFhirResourceDao<StructureDefinition> myStructureDefinitionDao;
private IFhirResourceDao<ValueSet> myValueSetDao;
private IFhirResourceDao<Questionnaire> myQuestionnaireDao;
private IFhirResourceDao<CodeSystem> myCodeSystemDao;
private IFhirResourceDao<ImplementationGuide> myImplementationGuideDao;
@Autowired
private FhirContext myR4Ctx;
private ApplicationContext myApplicationContext;
public class JpaValidationSupportR4 extends BaseJpaValidationSupport implements IJpaValidationSupportR4 {
/**
* Constructor
@ -92,77 +72,6 @@ public class JpaValidationSupportR4 implements IJpaValidationSupportR4, Applicat
return fetchResource(theCtx, ValueSet.class, theSystem);
}
@SuppressWarnings("unchecked")
@Override
public <T extends IBaseResource> T fetchResource(FhirContext theContext, Class<T> theClass, String theUri) {
IdType id = new IdType(theUri);
boolean localReference = false;
if (id.hasBaseUrl() == false && id.hasIdPart() == true) {
localReference = true;
}
String resourceName = myR4Ctx.getResourceDefinition(theClass).getName();
IBundleProvider search;
if ("ValueSet".equals(resourceName)) {
if (localReference) {
SearchParameterMap params = new SearchParameterMap();
params.setLoadSynchronousUpTo(1);
params.add(IAnyResource.SP_RES_ID, new StringParam(theUri));
search = myValueSetDao.search(params);
if (search.size() == 0) {
params = new SearchParameterMap();
params.setLoadSynchronousUpTo(1);
params.add(ValueSet.SP_URL, new UriParam(theUri));
search = myValueSetDao.search(params);
}
} else {
SearchParameterMap params = new SearchParameterMap();
params.setLoadSynchronousUpTo(1);
params.add(ValueSet.SP_URL, new UriParam(theUri));
search = myValueSetDao.search(params);
}
} else if ("StructureDefinition".equals(resourceName)) {
// Don't allow the core FHIR definitions to be overwritten
if (theUri.startsWith("http://hl7.org/fhir/StructureDefinition/")) {
String typeName = theUri.substring("http://hl7.org/fhir/StructureDefinition/".length());
if (myR4Ctx.getElementDefinition(typeName) != null) {
return null;
}
}
SearchParameterMap params = new SearchParameterMap();
params.setLoadSynchronousUpTo(1);
params.add(StructureDefinition.SP_URL, new UriParam(theUri));
search = myStructureDefinitionDao.search(params);
} else if ("Questionnaire".equals(resourceName)) {
SearchParameterMap params = new SearchParameterMap();
params.setLoadSynchronousUpTo(1);
params.add(IAnyResource.SP_RES_ID, new StringParam(id.getIdPart()));
search = myQuestionnaireDao.search(params);
} else if ("CodeSystem".equals(resourceName)) {
SearchParameterMap params = new SearchParameterMap();
params.setLoadSynchronousUpTo(1);
params.add(CodeSystem.SP_URL, new UriParam(theUri));
search = myCodeSystemDao.search(params);
} else if ("ImplementationGuide".equals(resourceName)) {
SearchParameterMap params = new SearchParameterMap();
params.setLoadSynchronousUpTo(1);
params.add(ImplementationGuide.SP_URL, new UriParam(theUri));
search = myImplementationGuideDao.search(params);
} else {
throw new IllegalArgumentException("Can't fetch resource type: " + resourceName);
}
if (search.size() == 0) {
return null;
}
if (search.size() > 1) {
ourLog.warn("Found multiple {} instances with URL search value of: {}", resourceName, theUri);
}
return (T) search.getResources(0, 1).get(0);
}
@Override
public StructureDefinition fetchStructureDefinition(FhirContext theCtx, String theUrl) {
return fetchResource(theCtx, StructureDefinition.class, theUrl);
@ -174,23 +83,9 @@ public class JpaValidationSupportR4 implements IJpaValidationSupportR4, Applicat
return false;
}
@Override
public void setApplicationContext(ApplicationContext theApplicationContext) throws BeansException {
myApplicationContext = theApplicationContext;
}
@PostConstruct
public void start() {
myStructureDefinitionDao = myApplicationContext.getBean("myStructureDefinitionDaoR4", IFhirResourceDao.class);
myValueSetDao = myApplicationContext.getBean("myValueSetDaoR4", IFhirResourceDao.class);
myQuestionnaireDao = myApplicationContext.getBean("myQuestionnaireDaoR4", IFhirResourceDao.class);
myCodeSystemDao = myApplicationContext.getBean("myCodeSystemDaoR4", IFhirResourceDao.class);
myImplementationGuideDao = myApplicationContext.getBean("myImplementationGuideDaoR4", IFhirResourceDao.class);
}
@Override
@Transactional(value = TxType.SUPPORTS)
public CodeValidationResult validateCode(FhirContext theCtx, String theCodeSystem, String theCode, String theDisplay) {
public IValidationSupport.CodeValidationResult validateCode(FhirContext theCtx, String theCodeSystem, String theCode, String theDisplay) {
return null;
}

View File

@ -1,22 +1,14 @@
package ca.uhn.fhir.jpa.dao.r5;
import ca.uhn.fhir.context.FhirContext;
import ca.uhn.fhir.jpa.dao.IFhirResourceDao;
import ca.uhn.fhir.jpa.searchparam.SearchParameterMap;
import ca.uhn.fhir.rest.api.server.IBundleProvider;
import ca.uhn.fhir.rest.param.StringParam;
import ca.uhn.fhir.rest.param.UriParam;
import org.hl7.fhir.instance.model.api.IAnyResource;
import ca.uhn.fhir.jpa.dao.r4.BaseJpaValidationSupport;
import org.hl7.fhir.instance.model.api.IBaseResource;
import org.hl7.fhir.r5.model.*;
import org.hl7.fhir.r5.model.CodeSystem;
import org.hl7.fhir.r5.model.StructureDefinition;
import org.hl7.fhir.r5.model.ValueSet;
import org.hl7.fhir.r5.model.ValueSet.ConceptSetComponent;
import org.hl7.fhir.r5.terminologies.ValueSetExpander;
import org.springframework.beans.BeansException;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.ApplicationContext;
import org.springframework.context.ApplicationContextAware;
import javax.annotation.PostConstruct;
import javax.transaction.Transactional;
import javax.transaction.Transactional.TxType;
import java.util.Collections;
@ -43,19 +35,7 @@ import java.util.List;
*/
@Transactional(value = TxType.REQUIRED)
public class JpaValidationSupportR5 implements IJpaValidationSupportR5, ApplicationContextAware {
private static final org.slf4j.Logger ourLog = org.slf4j.LoggerFactory.getLogger(JpaValidationSupportR5.class);
private IFhirResourceDao<StructureDefinition> myStructureDefinitionDao;
private IFhirResourceDao<ValueSet> myValueSetDao;
private IFhirResourceDao<Questionnaire> myQuestionnaireDao;
private IFhirResourceDao<CodeSystem> myCodeSystemDao;
private IFhirResourceDao<ImplementationGuide> myImplementationGuideDao;
@Autowired
private FhirContext myR5Ctx;
private ApplicationContext myApplicationContext;
public class JpaValidationSupportR5 extends BaseJpaValidationSupport implements IJpaValidationSupportR5 {
/**
* Constructor
@ -92,76 +72,6 @@ public class JpaValidationSupportR5 implements IJpaValidationSupportR5, Applicat
return fetchResource(theCtx, ValueSet.class, theSystem);
}
@SuppressWarnings("unchecked")
@Override
public <T extends IBaseResource> T fetchResource(FhirContext theContext, Class<T> theClass, String theUri) {
IdType id = new IdType(theUri);
boolean localReference = false;
if (id.hasBaseUrl() == false && id.hasIdPart() == true) {
localReference = true;
}
String resourceName = myR5Ctx.getResourceDefinition(theClass).getName();
IBundleProvider search;
if ("ValueSet".equals(resourceName)) {
if (localReference) {
SearchParameterMap params = new SearchParameterMap();
params.setLoadSynchronousUpTo(1);
params.add(IAnyResource.SP_RES_ID, new StringParam(theUri));
search = myValueSetDao.search(params);
if (search.size() == 0) {
params = new SearchParameterMap();
params.setLoadSynchronousUpTo(1);
params.add(ValueSet.SP_URL, new UriParam(theUri));
search = myValueSetDao.search(params);
}
} else {
SearchParameterMap params = new SearchParameterMap();
params.setLoadSynchronousUpTo(1);
params.add(ValueSet.SP_URL, new UriParam(theUri));
search = myValueSetDao.search(params);
}
} else if ("StructureDefinition".equals(resourceName)) {
// Don't allow the core FHIR definitions to be overwritten
if (theUri.startsWith("http://hl7.org/fhir/StructureDefinition/")) {
String typeName = theUri.substring("http://hl7.org/fhir/StructureDefinition/".length());
if (myR5Ctx.getElementDefinition(typeName) != null) {
return null;
}
}
SearchParameterMap params = new SearchParameterMap();
params.setLoadSynchronousUpTo(1);
params.add(StructureDefinition.SP_URL, new UriParam(theUri));
search = myStructureDefinitionDao.search(params);
} else if ("Questionnaire".equals(resourceName)) {
SearchParameterMap params = new SearchParameterMap();
params.setLoadSynchronousUpTo(1);
params.add(IAnyResource.SP_RES_ID, new StringParam(id.getIdPart()));
search = myQuestionnaireDao.search(params);
} else if ("CodeSystem".equals(resourceName)) {
SearchParameterMap params = new SearchParameterMap();
params.setLoadSynchronousUpTo(1);
params.add(CodeSystem.SP_URL, new UriParam(theUri));
search = myCodeSystemDao.search(params);
} else if ("ImplementationGuide".equals(resourceName)) {
SearchParameterMap params = new SearchParameterMap();
params.setLoadSynchronousUpTo(1);
params.add(ImplementationGuide.SP_URL, new UriParam(theUri));
search = myImplementationGuideDao.search(params);
} else {
throw new IllegalArgumentException("Can't fetch resource type: " + resourceName);
}
if (search.size() == 0) {
return null;
}
if (search.size() > 1) {
ourLog.warn("Found multiple {} instances with URL search value of: {}", resourceName, theUri);
}
return (T) search.getResources(0, 1).get(0);
}
@Override
public StructureDefinition fetchStructureDefinition(FhirContext theCtx, String theUrl) {
@ -174,19 +84,6 @@ public class JpaValidationSupportR5 implements IJpaValidationSupportR5, Applicat
return false;
}
@Override
public void setApplicationContext(ApplicationContext theApplicationContext) throws BeansException {
myApplicationContext = theApplicationContext;
}
@PostConstruct
public void start() {
myStructureDefinitionDao = myApplicationContext.getBean("myStructureDefinitionDaoR5", IFhirResourceDao.class);
myValueSetDao = myApplicationContext.getBean("myValueSetDaoR5", IFhirResourceDao.class);
myQuestionnaireDao = myApplicationContext.getBean("myQuestionnaireDaoR5", IFhirResourceDao.class);
myCodeSystemDao = myApplicationContext.getBean("myCodeSystemDaoR5", IFhirResourceDao.class);
myImplementationGuideDao = myApplicationContext.getBean("myImplementationGuideDaoR5", IFhirResourceDao.class);
}
@Override
@Transactional(value = TxType.SUPPORTS)

View File

@ -144,8 +144,8 @@ public class FhirResourceDaoR4ValidateTest extends BaseJpaR4Test {
}
private String encode(Patient thePatient) {
return myFhirCtx.newJsonParser().encodeResourceToString(thePatient);
private String encode(IBaseResource thePatient) {
return myFhirCtx.newJsonParser().setPrettyPrint(true).encodeResourceToString(thePatient);
}
@ -472,6 +472,85 @@ public class FhirResourceDaoR4ValidateTest extends BaseJpaR4Test {
}
}
@Test
public void testValidateQuestionnaireResponseWithCanonicalReference() {
Questionnaire q = new Questionnaire();
q.setId("q");
q.addItem().setLinkId("link0").setRequired(true).setType(Questionnaire.QuestionnaireItemType.STRING);
q.addItem().setLinkId("link1").setRequired(true).setType(Questionnaire.QuestionnaireItemType.STRING);
q.setUrl("http://foo/q");
myQuestionnaireDao.update(q);
QuestionnaireResponse qa = new QuestionnaireResponse();
qa.getText().setStatus(Narrative.NarrativeStatus.GENERATED).setDivAsString("<div>aaa</div>");
qa.setStatus(QuestionnaireResponse.QuestionnaireResponseStatus.COMPLETED);
qa.getQuestionnaireElement().setValue("http://foo/q");
qa.addItem().setLinkId("link1").addAnswer().setValue(new StringType("FOO"));
try {
MethodOutcome validationOutcome = myQuestionnaireResponseDao.validate(qa, null, null, null, null, null, null);
OperationOutcome oo = (OperationOutcome) validationOutcome.getOperationOutcome();
String encode = encode(oo);
ourLog.info(encode);
fail("Didn't fail- response was " + encode);
} catch (PreconditionFailedException e) {
OperationOutcome oo = (OperationOutcome) e.getOperationOutcome();
assertEquals("No response found for required item with id = 'link0'", oo.getIssueFirstRep().getDiagnostics());
}
}
@Test
public void testValidateQuestionnaireResponseWithLocalReference() {
Questionnaire q = new Questionnaire();
q.setId("q");
q.addItem().setLinkId("link0").setRequired(true).setType(Questionnaire.QuestionnaireItemType.STRING);
q.addItem().setLinkId("link1").setRequired(true).setType(Questionnaire.QuestionnaireItemType.STRING);
q.setUrl("http://foo/q");
myQuestionnaireDao.update(q);
QuestionnaireResponse qa = new QuestionnaireResponse();
qa.getText().setStatus(Narrative.NarrativeStatus.GENERATED).setDivAsString("<div>aaa</div>");
qa.setStatus(QuestionnaireResponse.QuestionnaireResponseStatus.COMPLETED);
qa.getQuestionnaireElement().setValue("Questionnaire/q");
qa.addItem().setLinkId("link1").addAnswer().setValue(new StringType("FOO"));
try {
MethodOutcome validationOutcome = myQuestionnaireResponseDao.validate(qa, null, null, null, null, null, null);
OperationOutcome oo = (OperationOutcome) validationOutcome.getOperationOutcome();
String encode = encode(oo);
ourLog.info(encode);
fail("Didn't fail- response was " + encode);
} catch (PreconditionFailedException e) {
OperationOutcome oo = (OperationOutcome) e.getOperationOutcome();
assertEquals("No response found for required item with id = 'link0'", oo.getIssueFirstRep().getDiagnostics());
}
}
@Test
public void testValidateQuestionnaireResponseWithUnknownReference() {
Questionnaire q = new Questionnaire();
q.setId("q");
q.addItem().setLinkId("link0").setRequired(true).setType(Questionnaire.QuestionnaireItemType.STRING);
q.addItem().setLinkId("link1").setRequired(true).setType(Questionnaire.QuestionnaireItemType.STRING);
q.setUrl("http://foo/q");
myQuestionnaireDao.update(q);
QuestionnaireResponse qa = new QuestionnaireResponse();
qa.getText().setStatus(Narrative.NarrativeStatus.GENERATED).setDivAsString("<div>aaa</div>");
qa.setStatus(QuestionnaireResponse.QuestionnaireResponseStatus.COMPLETED);
qa.getQuestionnaireElement().setValue("Questionnaire/DOES_NOT_EXIST");
qa.addItem().setLinkId("link1").addAnswer().setValue(new StringType("FOO"));
MethodOutcome validationOutcome = myQuestionnaireResponseDao.validate(qa, null, null, null, null, null, null);
OperationOutcome oo = (OperationOutcome) validationOutcome.getOperationOutcome();
assertEquals("The questionnaire \"Questionnaire/DOES_NOT_EXIST\" could not be resolved, so no validation can be performed against the base questionnaire", oo.getIssueFirstRep().getDiagnostics());
}
private IBaseResource findResourceByIdInBundle(Bundle vss, String name) {
IBaseResource retVal = null;
for (BundleEntryComponent next : vss.getEntry()) {

View File

@ -79,30 +79,6 @@ public class ResourceProviderQuestionnaireResponseDstu3Test extends BaseResource
}
}
@SuppressWarnings("unused")
@Test
@Ignore
public void testCreateWithAbsoluteReference() {
Patient pt1 = new Patient();
pt1.addName().setFamily("Everything").addGiven("Arthur");
IIdType ptId1 = myPatientDao.create(pt1, mySrd).getId().toUnqualifiedVersionless();
Questionnaire q1 = new Questionnaire();
q1.addItem().setLinkId("link1").setType(QuestionnaireItemType.STRING);
IIdType qId = myQuestionnaireDao.create(q1, mySrd).getId().toUnqualifiedVersionless();
QuestionnaireResponse qr1 = new QuestionnaireResponse();
qr1.getQuestionnaire().setReferenceElement(qId.withServerBase(null, "Questionnaire"));
qr1.setStatus(QuestionnaireResponseStatus.COMPLETED);
qr1.addItem().setLinkId("link1").addAnswer().setValue(new DecimalType(123));
try {
ourClient.create().resource(qr1).execute();
fail();
} catch (UnprocessableEntityException e) {
assertThat(e.toString(), containsString("Answer value must be of type string"));
}
}
@Test
public void testSaveQuestionnaire() throws Exception {
String input = "<QuestionnaireResponse xmlns=\"http://hl7.org/fhir\">\n" +

View File

@ -79,29 +79,6 @@ public class ResourceProviderQuestionnaireResponseR4Test extends BaseResourcePro
}
}
@SuppressWarnings("unused")
@Test
public void testCreateWithAbsoluteReference() {
Patient pt1 = new Patient();
pt1.addName().setFamily("Everything").addGiven("Arthur");
IIdType ptId1 = myPatientDao.create(pt1, mySrd).getId().toUnqualifiedVersionless();
Questionnaire q1 = new Questionnaire();
q1.addItem().setLinkId("link1").setType(QuestionnaireItemType.STRING);
IIdType qId = myQuestionnaireDao.create(q1, mySrd).getId().toUnqualifiedVersionless();
QuestionnaireResponse qr1 = new QuestionnaireResponse();
qr1.setQuestionnaire(qId.withServerBase("http://example.com", "Questionnaire").getValue());
qr1.setStatus(QuestionnaireResponseStatus.COMPLETED);
qr1.addItem().setLinkId("link1").addAnswer().setValue(new DecimalType(123));
try {
ourClient.create().resource(qr1).execute();
fail();
} catch (UnprocessableEntityException e) {
assertThat(myFhirCtx.newJsonParser().encodeResourceToString(e.getOperationOutcome()), containsString("Answer value must be of type string"));
}
}
@Test
public void testSaveQuestionnaire() throws Exception {
String input = "<QuestionnaireResponse xmlns=\"http://hl7.org/fhir\">\n" +

View File

@ -0,0 +1,40 @@
package ca.uhn.fhir.jpa.model.sched;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.Answers;
import org.mockito.Mock;
import org.mockito.junit.MockitoJUnitRunner;
import org.quartz.JobExecutionContext;
import static ca.uhn.fhir.jpa.model.sched.FireAtIntervalJob.NEXT_EXECUTION_TIME;
import static org.mockito.ArgumentMatchers.anyLong;
import static org.mockito.ArgumentMatchers.eq;
import static org.mockito.Mockito.times;
import static org.mockito.Mockito.verify;
@RunWith(MockitoJUnitRunner.class)
public class FireAtIntervalJobTest {
@Mock(answer = Answers.RETURNS_DEEP_STUBS)
private JobExecutionContext myJobExecutionContext;
@Test
public void testExecutionThrowsException() {
FireAtIntervalJob job = new FireAtIntervalJob(1000) {
@Override
protected void doExecute(JobExecutionContext theContext) {
throw new NullPointerException();
}
};
// No exception thrown please
job.execute(myJobExecutionContext);
verify(myJobExecutionContext.getJobDetail().getJobDataMap(), times(1)).put(eq(NEXT_EXECUTION_TIME), anyLong());
}
}

View File

@ -361,6 +361,11 @@ public abstract class BaseSearchParamRegistry<SP extends IBaseResource> implemen
return refreshCacheRetrier.runWithRetry();
}
@VisibleForTesting
public void setSearchParamProviderForUnitTest(ISearchParamProvider theSearchParamProvider) {
mySearchParamProvider = theSearchParamProvider;
}
@PostConstruct
public void registerScheduledJob() {
ScheduledJobDefinition jobDetail = new ScheduledJobDefinition();

View File

@ -367,6 +367,10 @@
The @Metadata annotation now has an attribute that can be used to control
the cache timeout
</action>
<action type="fix" issue="1544">
QuestionnaireResponse validation in the JPA server was not able to load Questionnaire resources that
were referenced using a canonical URI instead of a local reference. Thanks to Vu Vuong for reporting!
</action>
</release>
<release version="4.0.3" date="2019-09-03" description="Igloo (Point Release)">
<action type="fix">