Work on updating validator
This commit is contained in:
parent
d0bac3d419
commit
c96d5efe1f
|
@ -1,5 +1,7 @@
|
|||
package ca.uhn.fhir.jpa.dao;
|
||||
|
||||
import static org.apache.commons.lang3.StringUtils.isNotBlank;
|
||||
|
||||
import java.util.ArrayList;
|
||||
|
||||
/*
|
||||
|
@ -27,31 +29,37 @@ import java.util.List;
|
|||
|
||||
import org.hl7.fhir.instance.model.api.IBaseOperationOutcome;
|
||||
import org.hl7.fhir.instance.model.api.IBaseResource;
|
||||
import org.hl7.fhir.instance.validation.IResourceValidator.BestPracticeWarningLevel;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.beans.factory.annotation.Qualifier;
|
||||
|
||||
import ca.uhn.fhir.context.RuntimeResourceDefinition;
|
||||
import ca.uhn.fhir.context.RuntimeSearchParam;
|
||||
import ca.uhn.fhir.model.api.IResource;
|
||||
import ca.uhn.fhir.model.api.Include;
|
||||
import ca.uhn.fhir.model.base.composite.BaseResourceReferenceDt;
|
||||
import ca.uhn.fhir.model.base.resource.BaseOperationOutcome.BaseIssue;
|
||||
import ca.uhn.fhir.model.dstu2.resource.OperationOutcome;
|
||||
import ca.uhn.fhir.model.dstu2.resource.OperationOutcome.Issue;
|
||||
import ca.uhn.fhir.model.dstu2.valueset.IssueSeverityEnum;
|
||||
import ca.uhn.fhir.model.dstu2.valueset.IssueTypeEnum;
|
||||
import ca.uhn.fhir.model.primitive.IdDt;
|
||||
import ca.uhn.fhir.parser.IParser;
|
||||
import ca.uhn.fhir.parser.IParserErrorHandler;
|
||||
import ca.uhn.fhir.rest.api.MethodOutcome;
|
||||
import ca.uhn.fhir.rest.api.RestOperationTypeEnum;
|
||||
import ca.uhn.fhir.rest.api.ValidationModeEnum;
|
||||
import ca.uhn.fhir.rest.server.EncodingEnum;
|
||||
import ca.uhn.fhir.rest.server.interceptor.IServerInterceptor.ActionRequestDetails;
|
||||
import ca.uhn.fhir.util.FhirTerser;
|
||||
import ca.uhn.fhir.validation.DefaultProfileValidationSupport;
|
||||
import ca.uhn.fhir.validation.FhirInstanceValidator;
|
||||
import ca.uhn.fhir.validation.FhirValidator;
|
||||
import ca.uhn.fhir.validation.IValidationSupport;
|
||||
import ca.uhn.fhir.validation.ValidationResult;
|
||||
import ca.uhn.fhir.validation.ValidationSupportChain;
|
||||
|
||||
public class FhirResourceDaoDstu2<T extends IResource> extends BaseHapiFhirResourceDao<T> {
|
||||
|
||||
@Autowired
|
||||
@Qualifier("myJpaProfileValidationSupportDstu2")
|
||||
private IValidationSupport myJpaProfilealidationSupport;
|
||||
|
||||
@Override
|
||||
protected List<Object> getIncludeValues(FhirTerser theTerser, Include theInclude, IBaseResource theResource, RuntimeResourceDefinition theResourceDef) {
|
||||
List<Object> values;
|
||||
if ("*".equals(theInclude.getValue())) {
|
||||
|
@ -59,7 +67,7 @@ public class FhirResourceDaoDstu2<T extends IResource> extends BaseHapiFhirResou
|
|||
values.addAll(theTerser.getAllPopulatedChildElementsOfType(theResource, BaseResourceReferenceDt.class));
|
||||
} else if (theInclude.getValue().startsWith(theResourceDef.getName() + ":")) {
|
||||
values = new ArrayList<Object>();
|
||||
RuntimeSearchParam sp = theResourceDef.getSearchParam(theInclude.getValue().substring(theInclude.getValue().indexOf(':')+1));
|
||||
RuntimeSearchParam sp = theResourceDef.getSearchParam(theInclude.getValue().substring(theInclude.getValue().indexOf(':') + 1));
|
||||
for (String nextPath : sp.getPathsSplit()) {
|
||||
values.addAll(theTerser.getValues(theResource, nextPath));
|
||||
}
|
||||
|
@ -82,44 +90,23 @@ public class FhirResourceDaoDstu2<T extends IResource> extends BaseHapiFhirResou
|
|||
ActionRequestDetails requestDetails = new ActionRequestDetails(theId, null, theResource);
|
||||
notifyInterceptors(RestOperationTypeEnum.VALIDATE, requestDetails);
|
||||
|
||||
final OperationOutcome oo = new OperationOutcome();
|
||||
|
||||
IParser parser = theEncoding.newParser(getContext());
|
||||
parser.setParserErrorHandler(new IParserErrorHandler() {
|
||||
|
||||
@Override
|
||||
public void unknownAttribute(IParseLocation theLocation, String theAttributeName) {
|
||||
oo.addIssue().setSeverity(IssueSeverityEnum.ERROR).setCode(IssueTypeEnum.INVALID_CONTENT).setDiagnostics("Unknown attribute found: " + theAttributeName);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void unknownElement(IParseLocation theLocation, String theElementName) {
|
||||
oo.addIssue().setSeverity(IssueSeverityEnum.ERROR).setCode(IssueTypeEnum.INVALID_CONTENT).setDiagnostics("Unknown element found: " + theElementName);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void unexpectedRepeatingElement(IParseLocation theLocation, String theElementName) {
|
||||
oo.addIssue().setSeverity(IssueSeverityEnum.ERROR).setCode(IssueTypeEnum.INVALID_CONTENT).setDiagnostics("Multiple repetitions of non-repeatable element found: " + theElementName);
|
||||
}
|
||||
});
|
||||
|
||||
FhirValidator validator = getContext().newValidator();
|
||||
validator.setValidateAgainstStandardSchema(true);
|
||||
validator.setValidateAgainstStandardSchematron(true);
|
||||
ValidationResult result = validator.validateWithResult(theResource);
|
||||
OperationOutcome operationOutcome = (OperationOutcome) result.toOperationOutcome();
|
||||
for (BaseIssue next : operationOutcome.getIssue()) {
|
||||
oo.getIssue().add((Issue) next);
|
||||
|
||||
FhirInstanceValidator val = new FhirInstanceValidator();
|
||||
val.setBestPracticeWarningLevel(BestPracticeWarningLevel.Warning);
|
||||
val.setValidationSupport(new ValidationSupportChain(new DefaultProfileValidationSupport(), myJpaProfilealidationSupport));
|
||||
validator.registerValidatorModule(val);
|
||||
|
||||
ValidationResult result;
|
||||
if (isNotBlank(theRawResource)) {
|
||||
result = validator.validateWithResult(theRawResource);
|
||||
} else {
|
||||
result = validator.validateWithResult(theResource);
|
||||
}
|
||||
|
||||
// This method returns a MethodOutcome object
|
||||
MethodOutcome retVal = new MethodOutcome();
|
||||
oo.addIssue().setSeverity(IssueSeverityEnum.INFORMATION).setDiagnostics("Validation succeeded");
|
||||
retVal.setOperationOutcome(oo);
|
||||
|
||||
retVal.setOperationOutcome((OperationOutcome) result.toOperationOutcome());
|
||||
return retVal;
|
||||
}
|
||||
|
||||
|
||||
|
||||
}
|
||||
|
|
|
@ -0,0 +1,44 @@
|
|||
package ca.uhn.fhir.jpa.dao;
|
||||
|
||||
import org.hl7.fhir.instance.model.ValueSet;
|
||||
import org.hl7.fhir.instance.model.ValueSet.ConceptSetComponent;
|
||||
import org.hl7.fhir.instance.model.ValueSet.ValueSetExpansionComponent;
|
||||
import org.hl7.fhir.instance.model.api.IBaseResource;
|
||||
|
||||
import ca.uhn.fhir.context.FhirContext;
|
||||
import ca.uhn.fhir.validation.IValidationSupport;
|
||||
|
||||
|
||||
public class JpaProfileValidationSupport implements IValidationSupport {
|
||||
|
||||
@Override
|
||||
public ValueSetExpansionComponent expandValueSet(ConceptSetComponent theInclude) {
|
||||
// TODO Auto-generated method stub
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public ValueSet fetchCodeSystem(String theSystem) {
|
||||
// TODO Auto-generated method stub
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public <T extends IBaseResource> T fetchResource(FhirContext theContext, Class<T> theClass, String theUri) {
|
||||
// TODO Auto-generated method stub
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isCodeSystemSupported(String theSystem) {
|
||||
// TODO Auto-generated method stub
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public CodeValidationResult validateCode(String theCodeSystem, String theCode, String theDisplay) {
|
||||
// TODO Auto-generated method stub
|
||||
return null;
|
||||
}
|
||||
|
||||
}
|
|
@ -1,12 +1,16 @@
|
|||
package ca.uhn.fhir.jpa.dao;
|
||||
|
||||
import static org.junit.Assert.fail;
|
||||
import static org.mockito.Mockito.mock;
|
||||
|
||||
import java.util.List;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
|
||||
import javax.persistence.EntityManager;
|
||||
import javax.persistence.PersistenceContext;
|
||||
|
||||
import org.apache.commons.io.IOUtils;
|
||||
import org.hl7.fhir.instance.model.api.IBaseResource;
|
||||
import org.junit.Before;
|
||||
import org.junit.Test;
|
||||
import org.junit.runner.RunWith;
|
||||
|
@ -48,8 +52,10 @@ import ca.uhn.fhir.model.dstu2.resource.Patient;
|
|||
import ca.uhn.fhir.model.dstu2.resource.Practitioner;
|
||||
import ca.uhn.fhir.model.dstu2.resource.Questionnaire;
|
||||
import ca.uhn.fhir.model.dstu2.resource.QuestionnaireResponse;
|
||||
import ca.uhn.fhir.model.dstu2.resource.StructureDefinition;
|
||||
import ca.uhn.fhir.model.dstu2.resource.ValueSet;
|
||||
import ca.uhn.fhir.rest.server.IResourceProvider;
|
||||
import ca.uhn.fhir.parser.IParser;
|
||||
import ca.uhn.fhir.rest.method.MethodUtil;
|
||||
import ca.uhn.fhir.rest.server.interceptor.IServerInterceptor;
|
||||
|
||||
//@formatter:off
|
||||
|
@ -102,6 +108,9 @@ public class BaseJpaDstu2Test extends BaseJpaTest {
|
|||
@Qualifier("myResourceProvidersDstu2")
|
||||
protected Object myResourceProviders;
|
||||
@Autowired
|
||||
@Qualifier("myStructureDefinitionDaoDstu2")
|
||||
protected IFhirResourceDao<StructureDefinition> myStructureDefinitionDao;
|
||||
@Autowired
|
||||
@Qualifier("mySystemDaoDstu2")
|
||||
protected IFhirSystemDao<Bundle> mySystemDao;
|
||||
@Autowired
|
||||
|
@ -134,6 +143,16 @@ public class BaseJpaDstu2Test extends BaseJpaTest {
|
|||
// nothing
|
||||
}
|
||||
|
||||
protected <T extends IBaseResource> T loadResourceFromClasspath(Class<T> type, String resourceName) throws IOException {
|
||||
InputStream stream = FhirResourceDaoDstu2SearchTest.class.getResourceAsStream(resourceName);
|
||||
if (stream == null) {
|
||||
fail("Unable to load resource: " + resourceName);
|
||||
}
|
||||
String string = IOUtils.toString(stream, "UTF-8");
|
||||
IParser newJsonParser = MethodUtil.detectEncodingNoDefault(string).newParser(myFhirCtx);
|
||||
return newJsonParser.parseResource(type, string);
|
||||
}
|
||||
|
||||
public static void purgeDatabase(final EntityManager entityManager, PlatformTransactionManager theTxManager) {
|
||||
TransactionTemplate txTemplate = new TransactionTemplate(theTxManager);
|
||||
txTemplate.setPropagationBehavior(TransactionTemplate.PROPAGATION_REQUIRED);
|
||||
|
|
|
@ -19,7 +19,6 @@ import java.util.List;
|
|||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
|
||||
import org.apache.commons.io.IOUtils;
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
import org.hl7.fhir.instance.model.api.IBaseResource;
|
||||
import org.hl7.fhir.instance.model.api.IIdType;
|
||||
|
@ -1342,7 +1341,9 @@ public class FhirResourceDaoDstu2SearchTest extends BaseJpaDstu2Test {
|
|||
public void testSearchWithUriParam() throws Exception {
|
||||
String methodName = "testSearchWithUriParam";
|
||||
|
||||
ValueSet vs = myFhirCtx.newJsonParser().parseResource(ValueSet.class, IOUtils.toString(FhirResourceDaoDstu2SearchTest.class.getResourceAsStream("/valueset-dstu2.json")));
|
||||
Class<ValueSet> type = ValueSet.class;
|
||||
String resourceName = "/valueset-dstu2.json";
|
||||
ValueSet vs = loadResourceFromClasspath(type, resourceName);
|
||||
myValueSetDao.update(vs);
|
||||
|
||||
IBundleProvider result = myValueSetDao.search(ValueSet.SP_URL, new UriParam("http://hl7.org/fhir/ValueSet/basic-resource-type"));
|
||||
|
|
|
@ -0,0 +1,81 @@
|
|||
package ca.uhn.fhir.jpa.dao;
|
||||
|
||||
import static org.hamcrest.Matchers.containsString;
|
||||
import static org.junit.Assert.*;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.util.Arrays;
|
||||
|
||||
import org.junit.Test;
|
||||
|
||||
import ca.uhn.fhir.model.api.IResource;
|
||||
import ca.uhn.fhir.model.api.ResourceMetadataKeyEnum;
|
||||
import ca.uhn.fhir.model.dstu2.resource.Bundle;
|
||||
import ca.uhn.fhir.model.dstu2.resource.Bundle.Entry;
|
||||
import ca.uhn.fhir.model.dstu2.resource.Observation;
|
||||
import ca.uhn.fhir.model.dstu2.resource.StructureDefinition;
|
||||
import ca.uhn.fhir.model.dstu2.resource.ValueSet;
|
||||
import ca.uhn.fhir.model.dstu2.valueset.ObservationStatusEnum;
|
||||
import ca.uhn.fhir.model.primitive.IdDt;
|
||||
import ca.uhn.fhir.rest.api.MethodOutcome;
|
||||
import ca.uhn.fhir.rest.api.ValidationModeEnum;
|
||||
import ca.uhn.fhir.rest.server.EncodingEnum;
|
||||
|
||||
public class FhirResourceDaoDstu2ValidateTest extends BaseJpaDstu2Test {
|
||||
private static final org.slf4j.Logger ourLog = org.slf4j.LoggerFactory.getLogger(FhirResourceDaoDstu2ValidateTest.class);
|
||||
|
||||
@Test
|
||||
public void testValidateResourceContainingProfileDeclaration() throws Exception {
|
||||
String methodName = "testValidateResourceContainingProfileDeclaration";
|
||||
|
||||
Bundle vss = loadResourceFromClasspath(Bundle.class, "/org/hl7/fhir/instance/model/valueset/valuesets.xml");
|
||||
myValueSetDao.update((ValueSet) findResourceByIdInBundle(vss, "observation-status"));
|
||||
myValueSetDao.update((ValueSet) findResourceByIdInBundle(vss, "observation-category"));
|
||||
myValueSetDao.update((ValueSet) findResourceByIdInBundle(vss, "observation-codes"));
|
||||
myValueSetDao.update((ValueSet) findResourceByIdInBundle(vss, "observation-methods"));
|
||||
myValueSetDao.update((ValueSet) findResourceByIdInBundle(vss, "observation-valueabsentreason"));
|
||||
myValueSetDao.update((ValueSet) findResourceByIdInBundle(vss, "observation-interpretation"));
|
||||
myValueSetDao.update((ValueSet) findResourceByIdInBundle(vss, "body-site"));
|
||||
myValueSetDao.update((ValueSet) findResourceByIdInBundle(vss, "referencerange-meaning"));
|
||||
myValueSetDao.update((ValueSet) findResourceByIdInBundle(vss, "observation-relationshiptypes"));
|
||||
|
||||
StructureDefinition sd = loadResourceFromClasspath(StructureDefinition.class, "/org/hl7/fhir/instance/model/profile/devicemetricobservation.profile.xml");
|
||||
sd.setId(new IdDt());
|
||||
sd.setUrl("http://example.com/foo/bar/" + methodName);
|
||||
myStructureDefinitionDao.create(sd);
|
||||
|
||||
Observation input = new Observation();
|
||||
ResourceMetadataKeyEnum.PROFILES.put(input, Arrays.asList(new IdDt(sd.getUrl())));
|
||||
|
||||
input.addIdentifier().setSystem("http://acme").setValue("12345");
|
||||
input.getEncounter().setReference("http://foo.com/Encounter/9");
|
||||
input.setStatus(ObservationStatusEnum.FINAL);
|
||||
input.getCode().addCoding().setSystem("http://loinc.org").setCode("12345");
|
||||
|
||||
String encoded = myFhirCtx.newJsonParser().encodeResourceToString(input);
|
||||
ValidationModeEnum mode = ValidationModeEnum.CREATE;
|
||||
MethodOutcome outcome = myObservationDao.validate(input, null, encoded, EncodingEnum.JSON, mode, null);
|
||||
|
||||
String ooString = myFhirCtx.newJsonParser().setPrettyPrint(true).encodeResourceToString(outcome.getOperationOutcome());
|
||||
ourLog.info(ooString);
|
||||
assertThat(ooString, containsString("Element '/f:Observation.subject': minimum required = 1, but only found 0"));
|
||||
assertThat(ooString, containsString("Element encounter @ /f:Observation: max allowed = 0, but found 1"));
|
||||
assertThat(ooString, containsString("Element '/f:Observation.device': minimum required = 1, but only found 0"));
|
||||
|
||||
}
|
||||
|
||||
private IResource findResourceByIdInBundle(Bundle vss, String name) {
|
||||
IResource retVal = null;
|
||||
for (Entry next : vss.getEntry()) {
|
||||
if (next.getResource().getId().getIdPart().equals(name)) {
|
||||
retVal = next.getResource();
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (retVal == null) {
|
||||
fail("Can't find VS: " + name);
|
||||
}
|
||||
return retVal;
|
||||
}
|
||||
|
||||
}
|
|
@ -12,7 +12,6 @@ import org.hl7.fhir.instance.model.QuestionnaireResponse;
|
|||
import org.hl7.fhir.instance.model.ValueSet;
|
||||
import org.hl7.fhir.instance.model.api.IBaseResource;
|
||||
import org.hl7.fhir.instance.model.api.IIdType;
|
||||
import org.hl7.fhir.instance.model.valuesets.IssueType;
|
||||
import org.hl7.fhir.instance.utils.WorkerContext;
|
||||
import org.hl7.fhir.instance.validation.QuestionnaireResponseValidator;
|
||||
import org.hl7.fhir.instance.validation.ValidationMessage;
|
||||
|
|
|
@ -44,4 +44,8 @@
|
|||
|
||||
#end
|
||||
|
||||
#if ( ${versionCapitalized} == 'Dstu2' )
|
||||
<bean id="myJpaProfileValidationSupportDstu2" class="ca.uhn.fhir.jpa.dao.JpaProfileValidationSupport"/>
|
||||
#end
|
||||
|
||||
</beans>
|
Loading…
Reference in New Issue