Validator fixes

This commit is contained in:
James Agnew 2016-01-07 18:37:15 -05:00
parent c1afb4f54d
commit 50a9995c55
7 changed files with 137 additions and 33 deletions

View File

@ -209,7 +209,7 @@
<format>html</format> <format>html</format>
<format>xml</format> <format>xml</format>
</formats> </formats>
<maxmem>512m</maxmem> <maxmem>712m</maxmem>
<instrumentation> <instrumentation>
<ignores> <ignores>
<ignore>ca.uhn.fhir.model.dstu.valueset.*</ignore> <ignore>ca.uhn.fhir.model.dstu.valueset.*</ignore>

View File

@ -66,14 +66,11 @@ public class BaseDstu21Config extends BaseConfig {
} }
@Bean(name = "myJpaValidationSupportDstu21", autowire = Autowire.BY_NAME) @Bean(name = "myJpaValidationSupportDstu21", autowire = Autowire.BY_NAME)
public ca.uhn.fhir.jpa.dao.IJpaValidationSupportDstu21 jpaValidationSupportDstu21() { public static ca.uhn.fhir.jpa.dao.IJpaValidationSupportDstu21 jpaValidationSupportDstu21() {
ca.uhn.fhir.jpa.dao.JpaValidationSupportDstu21 retVal = new ca.uhn.fhir.jpa.dao.JpaValidationSupportDstu21(); ca.uhn.fhir.jpa.dao.JpaValidationSupportDstu21 retVal = new ca.uhn.fhir.jpa.dao.JpaValidationSupportDstu21();
return retVal; return retVal;
} }
@Qualifier("myJpaValidationSupportDstu21")
private IValidationSupport myJpaValidationSupportDstu21;
@Bean(autowire = Autowire.BY_TYPE) @Bean(autowire = Autowire.BY_TYPE)
public ISearchDao searchDaoDstu21() { public ISearchDao searchDaoDstu21() {
FhirSearchDao searchDao = new FhirSearchDao(); FhirSearchDao searchDao = new FhirSearchDao();
@ -98,8 +95,8 @@ public class BaseDstu21Config extends BaseConfig {
} }
@Bean @Bean
public IValidationSupport validationSupportChainDstu21() { public static IValidationSupport validationSupportChainDstu21() {
return new ValidationSupportChain(new DefaultProfileValidationSupport(), myJpaValidationSupportDstu21); return new ValidationSupportChain(new DefaultProfileValidationSupport(), jpaValidationSupportDstu21());
// return new ValidationSupportChain(); // return new ValidationSupportChain();
} }

View File

@ -69,8 +69,7 @@ public class FhirResourceDaoQuestionnaireResponseDstu21 extends FhirResourceDaoD
return; return;
} }
QuestionnaireResponse qa = (QuestionnaireResponse) theResource; if (theResource == null || theResource.getQuestionnaire() == null || theResource.getQuestionnaire().getReference() == null || theResource.getQuestionnaire().getReference().isEmpty()) {
if (qa == null || qa.getQuestionnaire() == null || qa.getQuestionnaire().getReference() == null || qa.getQuestionnaire().getReference().isEmpty()) {
return; return;
} }
@ -80,7 +79,7 @@ public class FhirResourceDaoQuestionnaireResponseDstu21 extends FhirResourceDaoD
val.registerValidatorModule(myQuestionnaireResponseValidatorDstu21); val.registerValidatorModule(myQuestionnaireResponseValidatorDstu21);
ValidationResult result = val.validateWithResult(getContext().newJsonParser().parseResource(getContext().newJsonParser().encodeResourceToString(qa))); ValidationResult result = val.validateWithResult(getContext().newJsonParser().parseResource(getContext().newJsonParser().encodeResourceToString(theResource)));
if (!result.isSuccessful()) { if (!result.isSuccessful()) {
IBaseOperationOutcome oo = getContext().newJsonParser().parseResource(OperationOutcome.class, getContext().newJsonParser().encodeResourceToString(result.toOperationOutcome())); IBaseOperationOutcome oo = getContext().newJsonParser().parseResource(OperationOutcome.class, getContext().newJsonParser().encodeResourceToString(result.toOperationOutcome()));
throw new UnprocessableEntityException(getContext(), oo); throw new UnprocessableEntityException(getContext(), oo);

View File

@ -1,10 +1,12 @@
package ca.uhn.fhir.jpa.dao; package ca.uhn.fhir.jpa.dao;
import org.hl7.fhir.dstu21.model.IdType; import org.hl7.fhir.dstu21.model.IdType;
import org.hl7.fhir.dstu21.model.Questionnaire;
import org.hl7.fhir.dstu21.model.StructureDefinition; import org.hl7.fhir.dstu21.model.StructureDefinition;
import org.hl7.fhir.dstu21.model.ValueSet; import org.hl7.fhir.dstu21.model.ValueSet;
import org.hl7.fhir.dstu21.model.ValueSet.ConceptSetComponent; import org.hl7.fhir.dstu21.model.ValueSet.ConceptSetComponent;
import org.hl7.fhir.dstu21.model.ValueSet.ValueSetExpansionComponent; import org.hl7.fhir.dstu21.model.ValueSet.ValueSetExpansionComponent;
import org.hl7.fhir.instance.model.api.IAnyResource;
/* /*
* #%L * #%L
@ -47,6 +49,10 @@ public class JpaValidationSupportDstu21 implements IJpaValidationSupportDstu21 {
@Qualifier("myValueSetDaoDstu21") @Qualifier("myValueSetDaoDstu21")
private IFhirResourceDao<ValueSet> myValueSetDao; private IFhirResourceDao<ValueSet> myValueSetDao;
@Autowired
@Qualifier("myQuestionnaireDaoDstu21")
private IFhirResourceDao<Questionnaire> myQuestionnaireDao;
@Autowired @Autowired
@Qualifier("myFhirContextDstu21") @Qualifier("myFhirContextDstu21")
private FhirContext myDstu21Ctx; private FhirContext myDstu21Ctx;
@ -73,12 +79,14 @@ public class JpaValidationSupportDstu21 implements IJpaValidationSupportDstu21 {
IBundleProvider search; IBundleProvider search;
if ("ValueSet".equals(resourceName)) { if ("ValueSet".equals(resourceName)) {
if (localReference) { if (localReference) {
search = myValueSetDao.search(ca.uhn.fhir.model.dstu2.resource.ValueSet.SP_RES_ID, new StringParam(theUri)); search = myValueSetDao.search(IAnyResource.SP_RES_ID, new StringParam(theUri));
} else { } else {
search = myValueSetDao.search(ca.uhn.fhir.model.dstu2.resource.ValueSet.SP_URL, new UriParam(theUri)); search = myValueSetDao.search(ValueSet.SP_URL, new UriParam(theUri));
} }
} else if ("StructureDefinition".equals(resourceName)) { } else if ("StructureDefinition".equals(resourceName)) {
search = myStructureDefinitionDao.search(ca.uhn.fhir.model.dstu2.resource.StructureDefinition.SP_URL, new UriParam(theUri)); search = myStructureDefinitionDao.search(StructureDefinition.SP_URL, new UriParam(theUri));
} else if ("Questionnaire".equals(resourceName)) {
search = myQuestionnaireDao.search(IAnyResource.SP_RES_ID, new StringParam(id.getIdPart()));
} else { } else {
throw new IllegalArgumentException("Can't fetch resource type: " + resourceName); throw new IllegalArgumentException("Can't fetch resource type: " + resourceName);
} }

View File

@ -42,6 +42,7 @@ public abstract class BaseResourceProviderDstu21Test extends BaseJpaDstu21Test {
protected static int ourPort; protected static int ourPort;
private static Server ourServer; private static Server ourServer;
protected static String ourServerBase; protected static String ourServerBase;
protected static RestfulServer ourRestServer;
public BaseResourceProviderDstu21Test() { public BaseResourceProviderDstu21Test() {
super(); super();
@ -81,21 +82,21 @@ public abstract class BaseResourceProviderDstu21Test extends BaseJpaDstu21Test {
if (ourServer == null) { if (ourServer == null) {
ourPort = RandomServerPortProvider.findFreePort(); ourPort = RandomServerPortProvider.findFreePort();
RestfulServer restServer = new RestfulServer(myFhirCtx); ourRestServer = new RestfulServer(myFhirCtx);
ourServerBase = "http://localhost:" + ourPort + "/fhir/context"; ourServerBase = "http://localhost:" + ourPort + "/fhir/context";
restServer.setResourceProviders((List)myResourceProviders); ourRestServer.setResourceProviders((List)myResourceProviders);
restServer.getFhirContext().setNarrativeGenerator(new DefaultThymeleafNarrativeGenerator()); ourRestServer.getFhirContext().setNarrativeGenerator(new DefaultThymeleafNarrativeGenerator());
restServer.setPlainProviders(mySystemProvider); ourRestServer.setPlainProviders(mySystemProvider);
JpaConformanceProviderDstu21 confProvider = new JpaConformanceProviderDstu21(restServer, mySystemDao, myDaoConfig); JpaConformanceProviderDstu21 confProvider = new JpaConformanceProviderDstu21(ourRestServer, mySystemDao, myDaoConfig);
confProvider.setImplementationDescription("THIS IS THE DESC"); confProvider.setImplementationDescription("THIS IS THE DESC");
restServer.setServerConformanceProvider(confProvider); ourRestServer.setServerConformanceProvider(confProvider);
restServer.setPagingProvider(new FifoMemoryPagingProvider(10)); ourRestServer.setPagingProvider(new FifoMemoryPagingProvider(10));
Server server = new Server(ourPort); Server server = new Server(ourPort);
@ -103,7 +104,7 @@ public abstract class BaseResourceProviderDstu21Test extends BaseJpaDstu21Test {
proxyHandler.setContextPath("/"); proxyHandler.setContextPath("/");
ServletHolder servletHolder = new ServletHolder(); ServletHolder servletHolder = new ServletHolder();
servletHolder.setServlet(restServer); servletHolder.setServlet(ourRestServer);
proxyHandler.addServlet(servletHolder, "/fhir/context/*"); proxyHandler.addServlet(servletHolder, "/fhir/context/*");
GenericWebApplicationContext webApplicationContext = new GenericWebApplicationContext(); GenericWebApplicationContext webApplicationContext = new GenericWebApplicationContext();

View File

@ -0,0 +1,95 @@
package ca.uhn.fhir.jpa.provider.dstu21;
import static org.hamcrest.Matchers.containsString;
import static org.junit.Assert.assertThat;
import static org.junit.Assert.fail;
import org.hl7.fhir.dstu21.model.DecimalType;
import org.hl7.fhir.dstu21.model.Patient;
import org.hl7.fhir.dstu21.model.Questionnaire;
import org.hl7.fhir.dstu21.model.Questionnaire.QuestionnaireItemType;
import org.hl7.fhir.dstu21.model.QuestionnaireResponse;
import org.hl7.fhir.dstu21.model.QuestionnaireResponse.QuestionnaireResponseStatus;
import org.hl7.fhir.instance.model.api.IIdType;
import org.junit.AfterClass;
import org.junit.Before;
import org.junit.Test;
import ca.uhn.fhir.rest.api.MethodOutcome;
import ca.uhn.fhir.rest.server.exceptions.UnprocessableEntityException;
import ca.uhn.fhir.rest.server.interceptor.RequestValidatingInterceptor;
import ca.uhn.fhir.rest.server.interceptor.ResponseValidatingInterceptor;
import ca.uhn.fhir.validation.IValidatorModule;
import ca.uhn.fhir.validation.ResultSeverityEnum;
public class ResourceProviderQuestionnaireResponseDstu21Test extends BaseResourceProviderDstu21Test {
private static final org.slf4j.Logger ourLog = org.slf4j.LoggerFactory.getLogger(ResourceProviderQuestionnaireResponseDstu21Test.class);
private static RequestValidatingInterceptor ourValidatingInterceptor;
@Override
@Before
public void before() throws Exception {
super.before();
if (ourValidatingInterceptor == null) {
ourValidatingInterceptor = new RequestValidatingInterceptor();
ourValidatingInterceptor.setFailOnSeverity(ResultSeverityEnum.ERROR);
for (IValidatorModule next : myAppCtx.getBeansOfType(IValidatorModule.class).values()) {
ourValidatingInterceptor.addValidatorModule(next);
}
ourRestServer.registerInterceptor(ourValidatingInterceptor);
}
}
@AfterClass
public static void afterClass() {
ourRestServer.unregisterInterceptor(ourValidatingInterceptor);
}
@Test
public void testCreateWithLocalReference() {
Patient pt1 = new Patient();
pt1.addName().addFamily("Everything").addGiven("Arthur");
IIdType ptId1 = myPatientDao.create(pt1).getId().toUnqualifiedVersionless();
Questionnaire q1 = new Questionnaire();
q1.addItem().setLinkId("link1").setType(QuestionnaireItemType.STRING);
IIdType qId = myQuestionnaireDao.create(q1).getId().toUnqualifiedVersionless();
QuestionnaireResponse qr1 = new QuestionnaireResponse();
qr1.getQuestionnaire().setReferenceElement(qId);
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 to question with linkId[link1] found of type [DecimalType] but this is invalid for question of type [string]"));
}
}
@Test
public void testCreateWithAbsoluteReference() {
Patient pt1 = new Patient();
pt1.addName().addFamily("Everything").addGiven("Arthur");
IIdType ptId1 = myPatientDao.create(pt1).getId().toUnqualifiedVersionless();
Questionnaire q1 = new Questionnaire();
q1.addItem().setLinkId("link1").setType(QuestionnaireItemType.STRING);
IIdType qId = myQuestionnaireDao.create(q1).getId().toUnqualifiedVersionless();
QuestionnaireResponse qr1 = new QuestionnaireResponse();
qr1.getQuestionnaire().setReferenceElement(qId.withServerBase("http://example.com", "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 to question with linkId[link1] found of type [DecimalType] but this is invalid for question of type [string]"));
}
}
}

View File

@ -2,6 +2,7 @@ package ca.uhn.fhirtest.config;
import java.util.Properties; import java.util.Properties;
import javax.annotation.PostConstruct;
import javax.persistence.EntityManagerFactory; import javax.persistence.EntityManagerFactory;
import javax.sql.DataSource; import javax.sql.DataSource;
@ -12,6 +13,7 @@ import org.springframework.beans.factory.annotation.Autowire;
import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier; import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.beans.factory.annotation.Value; import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.ApplicationContext;
import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration; import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.DependsOn; import org.springframework.context.annotation.DependsOn;
@ -43,12 +45,18 @@ public class TestDstu21Config extends BaseJavaConfigDstu21 {
private String myFhirLuceneLocation; private String myFhirLuceneLocation;
@Autowired @Autowired
@Qualifier("myInstanceValidatorDstu21") private ApplicationContext myApplicationCtx;
private IValidatorModule myInstanceValidatorDstu21;
@Autowired @PostConstruct
@Qualifier("myQuestionnaireResponseValidatorDstu21") public void postConstruct() {
private IValidatorModule myQuestionnaireResponseValidatorDstu21; IValidatorModule next = myApplicationCtx.getBean("myQuestionnaireResponseValidatorDstu21", IValidatorModule.class);
requestValidatingInterceptor().addValidatorModule(next);
responseValidatingInterceptor().addValidatorModule(next);
next = myApplicationCtx.getBean("myInstanceValidatorDstu21", IValidatorModule.class);
requestValidatingInterceptor().addValidatorModule(next);
responseValidatingInterceptor().addValidatorModule(next);
}
@Bean() @Bean()
public DaoConfig daoConfig() { public DaoConfig daoConfig() {
@ -104,10 +112,8 @@ public class TestDstu21Config extends BaseJavaConfigDstu21 {
* Bean which validates incoming requests * Bean which validates incoming requests
*/ */
@Bean @Bean
public IServerInterceptor requestValidatingInterceptor() { public RequestValidatingInterceptor requestValidatingInterceptor() {
RequestValidatingInterceptor requestValidator = new RequestValidatingInterceptor(); RequestValidatingInterceptor requestValidator = new RequestValidatingInterceptor();
requestValidator.addValidatorModule(myInstanceValidatorDstu21);
requestValidator.addValidatorModule(myQuestionnaireResponseValidatorDstu21);
requestValidator.setFailOnSeverity(ResultSeverityEnum.ERROR); requestValidator.setFailOnSeverity(ResultSeverityEnum.ERROR);
requestValidator.setAddResponseHeaderOnSeverity(null); requestValidator.setAddResponseHeaderOnSeverity(null);
requestValidator.setAddResponseOutcomeHeaderOnSeverity(ResultSeverityEnum.INFORMATION); requestValidator.setAddResponseOutcomeHeaderOnSeverity(ResultSeverityEnum.INFORMATION);
@ -119,10 +125,8 @@ public class TestDstu21Config extends BaseJavaConfigDstu21 {
* Bean which validates outgoing responses * Bean which validates outgoing responses
*/ */
@Bean @Bean
public IServerInterceptor responseValidatingInterceptor() { public ResponseValidatingInterceptor responseValidatingInterceptor() {
ResponseValidatingInterceptor responseValidator = new ResponseValidatingInterceptor(); ResponseValidatingInterceptor responseValidator = new ResponseValidatingInterceptor();
responseValidator.addValidatorModule(myInstanceValidatorDstu21);
responseValidator.addValidatorModule(myQuestionnaireResponseValidatorDstu21);
responseValidator.setResponseHeaderValueNoIssues("Validation did not detect any issues"); responseValidator.setResponseHeaderValueNoIssues("Validation did not detect any issues");
responseValidator.setFailOnSeverity(null); responseValidator.setFailOnSeverity(null);
responseValidator.setAddResponseHeaderOnSeverity(null); responseValidator.setAddResponseHeaderOnSeverity(null);