Skip to content

Commit

Permalink
Fix validating capabilitystatements (#2214)
Browse files Browse the repository at this point in the history
* Fix validating capabilitystatements

* Add changelog
  • Loading branch information
jamesagnew committed Dec 3, 2020
1 parent 7627a86 commit 35f4d48
Show file tree
Hide file tree
Showing 4 changed files with 108 additions and 52 deletions.
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
type: fix
issue: 2214
title: "When using the validator from within the JPA server, validating CapabilityStatement resources failed with
an error when trying to load linked SearchParameter resources. This has been corrected."
Original file line number Diff line number Diff line change
Expand Up @@ -119,71 +119,82 @@ public <T extends IBaseResource> T fetchResource(Class<T> theClass, String theUr

String resourceName = myFhirContext.getResourceType(theClass);
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 = myDaoRegistry.getResourceDao(resourceName).search(params);
if (search.size() == 0) {
params = new SearchParameterMap();
switch (resourceName) {
case "ValueSet":
if (localReference) {
SearchParameterMap params = new SearchParameterMap();
params.setLoadSynchronousUpTo(1);
params.add(IAnyResource.SP_RES_ID, new StringParam(theUri));
search = myDaoRegistry.getResourceDao(resourceName).search(params);
if (search.size() == 0) {
params = new SearchParameterMap();
params.setLoadSynchronousUpTo(1);
params.add(ValueSet.SP_URL, new UriParam(theUri));
search = myDaoRegistry.getResourceDao(resourceName).search(params);
}
} else {
int versionSeparator = theUri.lastIndexOf('|');
SearchParameterMap params = new SearchParameterMap();
params.setLoadSynchronousUpTo(1);
params.add(ValueSet.SP_URL, new UriParam(theUri));
if (versionSeparator != -1) {
params.add(ValueSet.SP_VERSION, new TokenParam(theUri.substring(versionSeparator + 1)));
params.add(ValueSet.SP_URL, new UriParam(theUri.substring(0, versionSeparator)));
} else {
params.add(ValueSet.SP_URL, new UriParam(theUri));
}
params.setSort(new SortSpec("_lastUpdated").setOrder(SortOrderEnum.DESC));
search = myDaoRegistry.getResourceDao(resourceName).search(params);
}
} else {
break;
case "StructureDefinition": {
// 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 (myFhirContext.getElementDefinition(typeName) != null) {
return myNoMatch;
}
}
SearchParameterMap params = new SearchParameterMap();
params.setLoadSynchronousUpTo(1);
params.add(StructureDefinition.SP_URL, new UriParam(theUri));
search = myDaoRegistry.getResourceDao("StructureDefinition").search(params);
break;
}
case "Questionnaire": {
SearchParameterMap params = new SearchParameterMap();
params.setLoadSynchronousUpTo(1);
if (localReference || myFhirContext.getVersion().getVersion().isEquivalentTo(FhirVersionEnum.DSTU2)) {
params.add(IAnyResource.SP_RES_ID, new StringParam(id.getIdPart()));
} else {
params.add(Questionnaire.SP_URL, new UriParam(id.getValue()));
}
search = myDaoRegistry.getResourceDao("Questionnaire").search(params);
break;
}
case "CodeSystem": {
int versionSeparator = theUri.lastIndexOf('|');
SearchParameterMap params = new SearchParameterMap();
params.setLoadSynchronousUpTo(1);
if (versionSeparator != -1) {
params.add(ValueSet.SP_VERSION, new TokenParam(theUri.substring(versionSeparator + 1)));
params.add(ValueSet.SP_URL, new UriParam(theUri.substring(0,versionSeparator)));
params.add(CodeSystem.SP_VERSION, new TokenParam(theUri.substring(versionSeparator + 1)));
params.add(CodeSystem.SP_URL, new UriParam(theUri.substring(0, versionSeparator)));
} else {
params.add(ValueSet.SP_URL, new UriParam(theUri));
params.add(CodeSystem.SP_URL, new UriParam(theUri));
}
params.setSort(new SortSpec("_lastUpdated").setOrder(SortOrderEnum.DESC));
search = myDaoRegistry.getResourceDao(resourceName).search(params);
break;
}
} 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 (myFhirContext.getElementDefinition(typeName) != null) {
return myNoMatch;
}
}
SearchParameterMap params = new SearchParameterMap();
params.setLoadSynchronousUpTo(1);
params.add(StructureDefinition.SP_URL, new UriParam(theUri));
search = myDaoRegistry.getResourceDao("StructureDefinition").search(params);
} else if ("Questionnaire".equals(resourceName)) {
SearchParameterMap params = new SearchParameterMap();
params.setLoadSynchronousUpTo(1);
if (localReference || myFhirContext.getVersion().getVersion().isEquivalentTo(FhirVersionEnum.DSTU2)) {
params.add(IAnyResource.SP_RES_ID, new StringParam(id.getIdPart()));
} else {
params.add(Questionnaire.SP_URL, new UriParam(id.getValue()));
}
search = myDaoRegistry.getResourceDao("Questionnaire").search(params);
} else if ("CodeSystem".equals(resourceName)) {
int versionSeparator = theUri.lastIndexOf('|');
SearchParameterMap params = new SearchParameterMap();
params.setLoadSynchronousUpTo(1);
if (versionSeparator != -1) {
params.add(CodeSystem.SP_VERSION, new TokenParam(theUri.substring(versionSeparator + 1)));
params.add(CodeSystem.SP_URL, new UriParam(theUri.substring(0,versionSeparator)));
} else {
params.add(CodeSystem.SP_URL, new UriParam(theUri));
case "ImplementationGuide":
case "SearchParameter": {
SearchParameterMap params = new SearchParameterMap();
params.setLoadSynchronousUpTo(1);
params.add(ImplementationGuide.SP_URL, new UriParam(theUri));
search = myDaoRegistry.getResourceDao(resourceName).search(params);
break;
}
params.setSort(new SortSpec("_lastUpdated").setOrder(SortOrderEnum.DESC));
search = myDaoRegistry.getResourceDao(resourceName).search(params);
} else if ("ImplementationGuide".equals(resourceName)) {
SearchParameterMap params = new SearchParameterMap();
params.setLoadSynchronousUpTo(1);
params.add(ImplementationGuide.SP_URL, new UriParam(theUri));
search = myDaoRegistry.getResourceDao("ImplementationGuide").search(params);
} else {
throw new IllegalArgumentException("Can't fetch resource type: " + resourceName);
default:
throw new IllegalArgumentException("Can't fetch resource type: " + resourceName);
}

Integer size = search.size();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -98,6 +98,7 @@
import org.hl7.fhir.r4.model.AuditEvent;
import org.hl7.fhir.r4.model.Binary;
import org.hl7.fhir.r4.model.Bundle;
import org.hl7.fhir.r4.model.CapabilityStatement;
import org.hl7.fhir.r4.model.CarePlan;
import org.hl7.fhir.r4.model.CareTeam;
import org.hl7.fhir.r4.model.ChargeItem;
Expand Down Expand Up @@ -356,6 +357,9 @@ public abstract class BaseJpaR4Test extends BaseJpaTest implements ITestDataBuil
@Qualifier("myDocumentReferenceDaoR4")
protected IFhirResourceDao<DocumentReference> myDocumentReferenceDao;
@Autowired
@Qualifier("myCapabilityStatementDaoR4")
protected IFhirResourceDao<CapabilityStatement> myCapabilityStatementDao;
@Autowired
@Qualifier("myPatientDaoR4")
protected IFhirResourceDaoPatient<Patient> myPatientDao;
@Autowired
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,7 @@
import org.hl7.fhir.r4.model.Bundle;
import org.hl7.fhir.r4.model.Bundle.BundleEntryComponent;
import org.hl7.fhir.r4.model.CanonicalType;
import org.hl7.fhir.r4.model.CapabilityStatement;
import org.hl7.fhir.r4.model.CodeSystem;
import org.hl7.fhir.r4.model.CodeType;
import org.hl7.fhir.r4.model.Coding;
Expand All @@ -56,6 +57,7 @@
import org.hl7.fhir.r4.model.Questionnaire;
import org.hl7.fhir.r4.model.QuestionnaireResponse;
import org.hl7.fhir.r4.model.Reference;
import org.hl7.fhir.r4.model.SearchParameter;
import org.hl7.fhir.r4.model.StringType;
import org.hl7.fhir.r4.model.StructureDefinition;
import org.hl7.fhir.r4.model.UriType;
Expand Down Expand Up @@ -1236,6 +1238,40 @@ public void after() {
myFhirCtx.setParserErrorHandler(new StrictErrorHandler());
}

@Test
public void testValidateCapabilityStatement() {

SearchParameter sp = new SearchParameter();
sp.setUrl("http://example.com/name");
sp.setId("name");
sp.setCode("name");
sp.setType(Enumerations.SearchParamType.STRING);
sp.setStatus(Enumerations.PublicationStatus.ACTIVE);
sp.addBase("Patient");
sp.setExpression("Patient.name");
mySearchParameterDao.update(sp);

CapabilityStatement cs = new CapabilityStatement();
cs.getText().setStatus(Narrative.NarrativeStatus.GENERATED).getDiv().setValue("<div>aaaa</div>");
CapabilityStatement.CapabilityStatementRestComponent rest = cs.addRest();
CapabilityStatement.CapabilityStatementRestResourceComponent patient = rest.addResource();
patient .setType("Patient");
patient.addSearchParam().setName("foo").setType(Enumerations.SearchParamType.DATE).setDefinition("http://example.com/name");


try {
myCapabilityStatementDao.validate(cs, null, null, null, ValidationModeEnum.CREATE, null, mySrd);
fail();
} catch (PreconditionFailedException e) {
String oo = myFhirCtx.newJsonParser().setPrettyPrint(true).encodeResourceToString(e.getOperationOutcome());
ourLog.info(oo);
assertThat(oo, oo, containsString("Type mismatch - SearchParameter 'http://example.com/name' type is string, but type here is date"));
}


}


@Test
public void testValidateForCreate() {
String methodName = "testValidateForCreate";
Expand Down

0 comments on commit 35f4d48

Please sign in to comment.