Test data uploader fixes

This commit is contained in:
James Agnew 2016-04-08 16:31:42 -04:00
parent 5cd13bc73f
commit 88157fe1a6
14 changed files with 407 additions and 15 deletions

View File

@ -171,7 +171,7 @@ public class GenericClient extends BaseClient implements IGenericClient {
@Override @Override
public BaseConformance conformance() { public BaseConformance conformance() {
if (myContext.getVersion().getVersion().equals(FhirVersionEnum.DSTU2_HL7ORG)) { if (myContext.getVersion().getVersion().equals(FhirVersionEnum.DSTU2_HL7ORG)) {
throw new IllegalArgumentException("Must call conformance(" + IBaseConformance.class.getSimpleName() + ") instead of conformance() for HL7.org structures"); throw new IllegalArgumentException("Must call fetchConformance() instead of conformance() for RI/DSTU3+ structures");
} }
HttpGetClientInvocation invocation = MethodUtil.createConformanceInvocation(getFhirContext()); HttpGetClientInvocation invocation = MethodUtil.createConformanceInvocation(getFhirContext());

View File

@ -1,5 +1,7 @@
package ca.uhn.fhir.rest.server.interceptor; package ca.uhn.fhir.rest.server.interceptor;
import static org.apache.commons.lang3.StringUtils.isBlank;
/* /*
* #%L * #%L
* HAPI FHIR - Core Library * HAPI FHIR - Core Library
@ -59,6 +61,12 @@ public class RequestValidatingInterceptor extends BaseValidatingInterceptor<Stri
Charset charset = ResourceParameter.determineRequestCharset(theRequestDetails); Charset charset = ResourceParameter.determineRequestCharset(theRequestDetails);
String requestText = new String(theRequestDetails.loadRequestContents(), charset); String requestText = new String(theRequestDetails.loadRequestContents(), charset);
if (isBlank(requestText)) {
ourLog.trace("Incoming request does not have a body");
return true;
}
validate(requestText, theRequestDetails); validate(requestText, theRequestDetails);
return true; return true;

View File

@ -39,7 +39,10 @@ import org.apache.http.client.methods.HttpGet;
import org.apache.http.impl.client.CloseableHttpClient; import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.HttpClientBuilder; import org.apache.http.impl.client.HttpClientBuilder;
import org.fusesource.jansi.Ansi; import org.fusesource.jansi.Ansi;
import org.hl7.fhir.dstu3.hapi.validation.DefaultProfileValidationSupport;
import org.hl7.fhir.dstu3.hapi.validation.FhirInstanceValidator;
import org.hl7.fhir.dstu3.model.Bundle.BundleEntryComponent; import org.hl7.fhir.dstu3.model.Bundle.BundleEntryComponent;
import org.hl7.fhir.dstu3.model.Bundle.BundleType;
import org.hl7.fhir.dstu3.model.Bundle.HTTPVerb; import org.hl7.fhir.dstu3.model.Bundle.HTTPVerb;
import org.hl7.fhir.dstu3.model.IdType; import org.hl7.fhir.dstu3.model.IdType;
import org.hl7.fhir.dstu3.model.Resource; import org.hl7.fhir.dstu3.model.Resource;
@ -60,6 +63,8 @@ import ca.uhn.fhir.parser.DataFormatException;
import ca.uhn.fhir.rest.client.IGenericClient; import ca.uhn.fhir.rest.client.IGenericClient;
import ca.uhn.fhir.rest.client.apache.GZipContentInterceptor; import ca.uhn.fhir.rest.client.apache.GZipContentInterceptor;
import ca.uhn.fhir.util.ResourceReferenceInfo; import ca.uhn.fhir.util.ResourceReferenceInfo;
import ca.uhn.fhir.validation.FhirValidator;
import ca.uhn.fhir.validation.ValidationResult;
public class ExampleDataUploader extends BaseCommand { public class ExampleDataUploader extends BaseCommand {
@ -369,9 +374,10 @@ public class ExampleDataUploader extends BaseCommand {
Map<String, Integer> ids = new HashMap<String, Integer>(); Map<String, Integer> ids = new HashMap<String, Integer>();
Set<String> fullIds = new HashSet<String>(); Set<String> fullIds = new HashSet<String>();
for (Iterator<BundleEntryComponent> iterator = bundle.getEntry().iterator(); iterator.hasNext();) { for (Iterator<BundleEntryComponent> iterator = bundle.getEntry().iterator(); iterator.hasNext();) {
BundleEntryComponent next = iterator.next(); BundleEntryComponent next = iterator.next();
// DataElement have giant IDs that seem invalid, need to investigate this.. // DataElement have giant IDs that seem invalid, need to investigate this..
if ("DataElement".equals(next.getResource().getResourceType().name()) || "OperationOutcome".equals(next.getResource().getResourceType().name()) || "OperationDefinition".equals(next.getResource().getResourceType().name())) { if ("DataElement".equals(next.getResource().getResourceType().name()) || "OperationOutcome".equals(next.getResource().getResourceType().name()) || "OperationDefinition".equals(next.getResource().getResourceType().name())) {
ourLog.info("Skipping " + next.getResource().getResourceType().name() + " example"); ourLog.info("Skipping " + next.getResource().getResourceType().name() + " example");
@ -530,6 +536,10 @@ public class ExampleDataUploader extends BaseCommand {
throws IOException, UnsupportedEncodingException { throws IOException, UnsupportedEncodingException {
org.hl7.fhir.dstu3.model.Bundle bundle = new org.hl7.fhir.dstu3.model.Bundle(); org.hl7.fhir.dstu3.model.Bundle bundle = new org.hl7.fhir.dstu3.model.Bundle();
bundle.setType(BundleType.TRANSACTION);
FhirValidator val = ctx.newValidator();
val.registerValidatorModule(new FhirInstanceValidator(new DefaultProfileValidationSupport()));
ZipInputStream zis = new ZipInputStream(FileUtils.openInputStream(inputFile)); ZipInputStream zis = new ZipInputStream(FileUtils.openInputStream(inputFile));
byte[] buffer = new byte[2048]; byte[] buffer = new byte[2048];
@ -567,6 +577,12 @@ public class ExampleDataUploader extends BaseCommand {
} }
ourLog.info("Found example {} - {} - {} chars", nextEntry.getName(), parsed.getClass().getSimpleName(), exampleString.length()); ourLog.info("Found example {} - {} - {} chars", nextEntry.getName(), parsed.getClass().getSimpleName(), exampleString.length());
ValidationResult result = val.validateWithResult(parsed);
if (result.isSuccessful() == false) {
ourLog.info("FAILED to validate example {}", nextEntry.getName());
continue;
}
if (ctx.getResourceDefinition(parsed).getName().equals("Bundle")) { if (ctx.getResourceDefinition(parsed).getName().equals("Bundle")) {
BaseRuntimeChildDefinition entryChildDef = ctx.getResourceDefinition(parsed).getChildByName("entry"); BaseRuntimeChildDefinition entryChildDef = ctx.getResourceDefinition(parsed).getChildByName("entry");
BaseRuntimeElementCompositeDefinition<?> entryDef = (BaseRuntimeElementCompositeDefinition<?>) entryChildDef.getChildByName("entry"); BaseRuntimeElementCompositeDefinition<?> entryDef = (BaseRuntimeElementCompositeDefinition<?>) entryChildDef.getChildByName("entry");
@ -577,7 +593,10 @@ public class ExampleDataUploader extends BaseCommand {
continue; continue;
} }
for (IBase nextResource : resources) { for (IBase nextResource : resources) {
if (!ctx.getResourceDefinition(parsed).getName().equals("Bundle") && ctx.getResourceDefinition(parsed).getName().equals("SearchParameter")) { if (nextResource == null) {
continue;
}
if (!ctx.getResourceDefinition((Class<? extends IBaseResource>) nextResource.getClass()).getName().equals("Bundle") && ctx.getResourceDefinition((Class<? extends IBaseResource>) nextResource.getClass()).getName().equals("SearchParameter")) {
BundleEntryComponent entry = bundle.addEntry(); BundleEntryComponent entry = bundle.addEntry();
entry.getRequest().setMethod(HTTPVerb.POST); entry.getRequest().setMethod(HTTPVerb.POST);
entry.setResource((Resource) nextResource); entry.setResource((Resource) nextResource);

View File

@ -84,6 +84,9 @@ public class StaleSearchDeletingSvc {
} }
}); });
} }
ourLog.info("Deleted {} searches, {} remaining", toDelete.size(), mySearchDao.count());
} }
} }

View File

@ -26,7 +26,6 @@ import ca.uhn.fhir.model.dstu2.resource.Bundle;
import ca.uhn.fhir.narrative.DefaultThymeleafNarrativeGenerator; import ca.uhn.fhir.narrative.DefaultThymeleafNarrativeGenerator;
import ca.uhn.fhir.rest.server.ETagSupportEnum; import ca.uhn.fhir.rest.server.ETagSupportEnum;
import ca.uhn.fhir.rest.server.EncodingEnum; import ca.uhn.fhir.rest.server.EncodingEnum;
import ca.uhn.fhir.rest.server.FifoMemoryPagingProvider;
import ca.uhn.fhir.rest.server.IResourceProvider; import ca.uhn.fhir.rest.server.IResourceProvider;
import ca.uhn.fhir.rest.server.RestfulServer; import ca.uhn.fhir.rest.server.RestfulServer;
import ca.uhn.fhir.rest.server.interceptor.IServerInterceptor; import ca.uhn.fhir.rest.server.interceptor.IServerInterceptor;
@ -148,6 +147,14 @@ public class JpaServerDemo extends RestfulServer {
this.registerInterceptor(interceptor); this.registerInterceptor(interceptor);
} }
/*
* If you are hosting this server at a specific DNS name, the server will try to
* figure out the FHIR base URL based on what the web container tells it, but
* this doesn't always work. If you are setting links in your search bundles that
* just refer to "localhost", you might want to use a server address strategy:
*/
//setServerAddressStrategy(new HardcodedServerAddressStrategy("http://mydomain.com/fhir/baseDstu2"));
} }
} }

View File

@ -102,7 +102,7 @@
<servlet-class>ca.uhn.fhirtest.TestRestfulServer</servlet-class> <servlet-class>ca.uhn.fhirtest.TestRestfulServer</servlet-class>
<init-param> <init-param>
<param-name>ImplementationDescription</param-name> <param-name>ImplementationDescription</param-name>
<param-value>UHN Test Server (DSTU 2.1 Resources)</param-value> <param-value>UHN Test Server (DSTU 3 Resources)</param-value>
</init-param> </init-param>
<init-param> <init-param>
<param-name>FhirVersion</param-name> <param-name>FhirVersion</param-name>

View File

@ -9,7 +9,7 @@
</encoder> </encoder>
</appender> </appender>
<logger name="org.hibernate.SQL" additivity="false" level="trace"> <logger name="org.hibernate.SQL" additivity="false" level="info">
<appender-ref ref="STDOUT" /> <appender-ref ref="STDOUT" />
</logger> </logger>

View File

@ -187,7 +187,7 @@ public class ServerConformanceProvider implements IServerConformanceProvider<Con
retVal.setPublisher(myPublisher); retVal.setPublisher(myPublisher);
retVal.setDateElement(conformanceDate()); retVal.setDateElement(conformanceDate());
retVal.setFhirVersion("1.0.2"); // TODO: pull from model retVal.setFhirVersion("1.4.0"); // TODO: pull from model
retVal.setAcceptUnknown(UnknownContentCode.EXTENSIONS); // TODO: make this configurable - this is a fairly big retVal.setAcceptUnknown(UnknownContentCode.EXTENSIONS); // TODO: make this configurable - this is a fairly big
// effort since the parser // effort since the parser
// needs to be modified to actually allow it // needs to be modified to actually allow it

View File

@ -179,14 +179,16 @@ public class ProfileUtilities {
// if we have a name reference, we have to find it, and iterate it's children // if we have a name reference, we have to find it, and iterate it's children
if (contentReference != null) { if (contentReference != null) {
boolean found = false; boolean found = false;
String candidateName = profile.getName() + "." + contentReference.substring(1);
for (ElementDefinition e : profile.getSnapshot().getElement()) { for (ElementDefinition e : profile.getSnapshot().getElement()) {
if (e.getPath().equals(candidateName)) { String elementPath = e.getPath();
if (elementPath.startsWith(profile.getName()) && elementPath.endsWith("." + contentReference.substring(1))) {
found = true; found = true;
path = e.getPath(); path = elementPath;
break;
} else if (contentReference.equals("#"+e.getId())) { } else if (contentReference.equals("#"+e.getId())) {
found = true; found = true;
path = e.getPath(); path = elementPath;
break;
} }
} }
if (!found) if (!found)

View File

@ -1333,6 +1333,9 @@ public class InstanceValidator extends BaseValidator implements IResourceValidat
// } // }
private boolean passesCodeWhitespaceRules(String v) { private boolean passesCodeWhitespaceRules(String v) {
if (v == null) {
return true;
}
if (!v.trim().equals(v)) if (!v.trim().equals(v))
return false; return false;
boolean lastWasSpace = true; boolean lastWasSpace = true;
@ -2161,7 +2164,7 @@ public class InstanceValidator extends BaseValidator implements IResourceValidat
NodeStack firstStack = stack.push(firstEntry, 0, null, null); NodeStack firstStack = stack.push(firstEntry, 0, null, null);
String fullUrl = firstEntry.getNamedChildValue("fullUrl"); String fullUrl = firstEntry.getNamedChildValue("fullUrl");
if (type.equals("document")) { if ("document".equals(type)) {
WrapperElement res = firstEntry.getNamedChild("resource"); WrapperElement res = firstEntry.getNamedChild("resource");
NodeStack localStack = firstStack.push(res, -1, null, null); NodeStack localStack = firstStack.push(res, -1, null, null);
WrapperElement resource = res.getFirstChild(); WrapperElement resource = res.getFirstChild();
@ -2173,7 +2176,7 @@ public class InstanceValidator extends BaseValidator implements IResourceValidat
validateDocument(errors, entries, res, localStack, fullUrl, id); validateDocument(errors, entries, res, localStack, fullUrl, id);
} }
} }
if (type.equals("message")) if ("message".equals(type))
validateMessage(errors, bundle); validateMessage(errors, bundle);
} }
} }
@ -2475,8 +2478,9 @@ public class InstanceValidator extends BaseValidator implements IResourceValidat
match = sliceMatches(ei.element, ei.path, slice, ed, profile); match = sliceMatches(ei.element, ei.path, slice, ed, profile);
} }
if (match) { if (match) {
if (rule(errors, IssueType.INVALID, ei.line(), ei.col(), ei.path, ei.definition == null, "Element matches more than one slice")) if (rule(errors, IssueType.INVALID, ei.line(), ei.col(), ei.path, ei.definition == null, "Element matches more than one slice")) {
ei.definition = ed; ei.definition = ed;
}
} }
} }
} }

View File

@ -104,6 +104,27 @@ public class RequestValidatingInterceptorDstu3Test {
assertThat(responseContent, containsString("<severity value=\"error\"/>")); assertThat(responseContent, containsString("<severity value=\"error\"/>"));
} }
@Test
public void testFetchMetadata() throws Exception {
myInterceptor.setAddResponseHeaderOnSeverity(ResultSeverityEnum.INFORMATION);
HttpGet httpGet = new HttpGet("http://localhost:" + ourPort + "/metadata");
// This header caused a crash
httpGet.addHeader("Content-Type", "application/xml+fhir");
HttpResponse status = ourClient.execute(httpGet);
String responseContent = IOUtils.toString(status.getEntity().getContent());
IOUtils.closeQuietly(status.getEntity().getContent());
ourLog.info("Response was:\n{}", status);
ourLog.info("Response was:\n{}", responseContent);
assertEquals(200, status.getStatusLine().getStatusCode());
assertThat(responseContent, containsString("Conformance"));
}
@Test @Test
public void testCreateJsonInvalidNoFailure() throws Exception { public void testCreateJsonInvalidNoFailure() throws Exception {
myInterceptor.setFailOnSeverity(null); myInterceptor.setFailOnSeverity(null);

View File

@ -225,6 +225,22 @@ public class FhirInstanceValidatorDstu3Test {
assertEquals("Element is unknown or does not match any slice", output.getMessages().get(0).getMessage()); assertEquals("Element is unknown or does not match any slice", output.getMessages().get(0).getMessage());
} }
@Test
public void testValidateRawJsonResourceFromExamples() throws Exception {
// @formatter:off
String input = IOUtils.toString(FhirInstanceValidator.class.getResourceAsStream("/testscript-search.json"));
// @formatter:on
ValidationResult output = myVal.validateWithResult(input);
logResultsAndReturnNonInformationalOnes(output);
// assertEquals(output.toString(), 1, output.getMessages().size());
// ourLog.info(output.getMessages().get(0).getLocationString());
// ourLog.info(output.getMessages().get(0).getMessage());
// assertEquals("/foo", output.getMessages().get(0).getLocationString());
// assertEquals("Element is unknown or does not match any slice", output.getMessages().get(0).getMessage());
}
@Test @Test
public void testValidateRawXmlResource() { public void testValidateRawXmlResource() {
// @formatter:off // @formatter:off

View File

@ -0,0 +1,298 @@
{
"resourceType": "TestScript",
"id": "search",
"text": {
"status": "generated",
"div": "<div><p><b>Generated Narrative with Details</b></p><p><b>id</b>: search</p><p><b>name</b>: Read, Search and Conditional Create and Delete</p><p><b>description</b>: Test Script for testing search, read, and conditional create and delete</p><h3>Fixtures</h3><table><tr><td>-</td><td><b>Resource</b></td></tr><tr><td>*</td><td><a>Patient/patient-example.xml</a></td></tr></table><blockquote><p><b>variable</b></p><p><b>name</b>: V1</p><p><b>sourceId</b>: R1</p><p><b>headerField</b>: Location</p></blockquote><blockquote><p><b>variable</b></p><p><b>name</b>: V2</p><p><b>sourceId</b>: R3</p><p><b>path</b>: fhir:Patient/fhir:name/fhir:given/@value</p></blockquote><blockquote><p><b>setup</b></p><blockquote><p><b>action</b></p><h3>Operations</h3><table><tr><td>-</td><td><b>Type</b></td><td><b>Resource</b></td><td><b>Params</b></td></tr><tr><td>*</td><td>delete</td><td>Patient</td><td>given=John&amp;family=Doe</td></tr></table></blockquote></blockquote><blockquote><p><b>test</b></p><p><b>name</b>: Create</p><p><b>description</b>: Create, read, search, conditional create, conditional delete.</p><blockquote><p><b>metadata</b></p><h3>Links</h3><table><tr><td>-</td><td><b>Url</b></td><td><b>Description</b></td></tr><tr><td>*</td><td><a>http://hl7.org/implement/standards/FHIR-Develop/patient.html</a></td><td>FHIR Patient</td></tr></table><blockquote><p><b>operation</b></p><p><b>type</b>: create</p><p><b>resource</b>: Patient</p><p><b>description</b>: Conditional Create Operation</p><p><b>link</b>: <a>http://hl7-fhir.github.io/http.html#2.1.0.13.1</a></p><p><b>required</b>: true</p><p><b>validated</b>: true</p></blockquote><blockquote><p><b>operation</b></p><p><b>type</b>: delete</p><p><b>resource</b>: Patient</p><p><b>description</b>: Conditional Delete Operation</p><p><b>link</b>: <a>http://hl7-fhir.github.io/http.html#2.1.0.12.1</a></p><p><b>required</b>: true</p><p><b>validated</b>: true</p></blockquote><blockquote><p><b>operation</b></p><p><b>type</b>: read</p><p><b>resource</b>: Patient</p><p><b>description</b>: Patient Read Operation</p><p><b>link</b>: <a>http://hl7.org/implement/standards/FHIR-Develop/http.html#read</a></p><p><b>validated</b>: true</p></blockquote><blockquote><p><b>operation</b></p><p><b>type</b>: search</p><p><b>resource</b>: Patient</p><p><b>description</b>: Patient Search Operation</p><p><b>link</b>: <a>http://hl7-fhir.github.io/http.html#2.1.0.14</a></p><p><b>validated</b>: true</p></blockquote></blockquote><blockquote><p><b>action</b></p><h3>Operations</h3><table><tr><td>-</td></tr><tr><td>*</td></tr></table></blockquote><blockquote><p><b>action</b></p><h3>Asserts</h3><table><tr><td>-</td></tr><tr><td>*</td></tr></table></blockquote><blockquote><p><b>action</b></p><h3>Operations</h3><table><tr><td>-</td></tr><tr><td>*</td></tr></table></blockquote><blockquote><p><b>action</b></p><h3>Asserts</h3><table><tr><td>-</td></tr><tr><td>*</td></tr></table></blockquote><blockquote><p><b>action</b></p><h3>Asserts</h3><table><tr><td>-</td></tr><tr><td>*</td></tr></table></blockquote><blockquote><p><b>action</b></p><h3>Operations</h3><table><tr><td>-</td></tr><tr><td>*</td></tr></table></blockquote><blockquote><p><b>action</b></p><h3>Asserts</h3><table><tr><td>-</td></tr><tr><td>*</td></tr></table></blockquote><blockquote><p><b>action</b></p><h3>Asserts</h3><table><tr><td>-</td></tr><tr><td>*</td></tr></table></blockquote><blockquote><p><b>action</b></p><h3>Operations</h3><table><tr><td>-</td></tr><tr><td>*</td></tr></table></blockquote><blockquote><p><b>action</b></p><h3>Asserts</h3><table><tr><td>-</td></tr><tr><td>*</td></tr></table></blockquote><blockquote><p><b>action</b></p><h3>Asserts</h3><table><tr><td>-</td></tr><tr><td>*</td></tr></table></blockquote><blockquote><p><b>action</b></p><h3>Asserts</h3><table><tr><td>-</td></tr><tr><td>*</td></tr></table></blockquote><blockquote><p><b>action</b></p><h3>Asserts</h3><table><tr><td>-</td></tr><tr><td>*</td></tr></table></blockquote><blockquote><p><b>action</b></p><h3>Operations</h3><table><tr><td>-</td></tr><tr><td>*</td></tr></table></blockquote><blockquote><p><b>action</b></p><h3>Asserts</h3><table><tr><td>-</td></tr><tr><td>*</td></tr></table></blockquote><blockquote><p><b>action</b></p><h3>Operations</h3><table><tr><td>-</td></tr><tr><td>*</td></tr></table></blockquote><blockquote><p><b>action</b></p><h3>Operations</h3><table><tr><td>-</td></tr><tr><td>*</td></tr></table></blockquote><blockquote><p><b>action</b></p><h3>Asserts</h3><table><tr><td>-</td></tr><tr><td>*</td></tr></table></blockquote></blockquote></div>"
},
"url": "http://hl7.org/fhir/TestScript/search",
"name": "Read, Search and Conditional Create and Delete",
"status": "draft",
"description": "Test Script for testing search, read, and conditional create and delete",
"metadata": {
"capability": [
{
"required": true,
"description": "Patient Create and Read Operations",
"link": [
"http://hl7.org/implement/standards/FHIR-Develop/http.html#create",
"http://hl7.org/implement/standards/FHIR-Develop/http.html#read"
],
"conformance": {
"reference": "Conformance/example"
}
},
{
"required": true,
"description": "Patient Conditional Delete Operation",
"link": [
"http://hl7-fhir.github.io/http.html#2.1.0.12.1"
],
"conformance": {
"reference": "Conformance/example"
}
},
{
"required": true,
"description": "Patient Conditional Create Operation",
"link": [
"http://hl7-fhir.github.io/http.html#2.1.0.13.1"
],
"conformance": {
"reference": "Conformance/example"
}
}
]
},
"fixture": [
{
"id": "example-patient",
"resource": {
"reference": "Patient/example"
}
}
],
"variable": [
{
"name": "V1",
"headerField": "Location",
"sourceId": "R1"
},
{
"name": "V2",
"path": "fhir:Patient/fhir:name/fhir:given/@value",
"sourceId": "R3"
},
{
"name": "DefaultValue",
"defaultValue": "Replace at Runtime"
}
],
"setup": {
"action": [
{
"fhir_comments": [
" Conditional Delete "
],
"operation": {
"type": {
"code": "delete"
},
"resource": "Patient",
"params": "given=John&family=Doe"
}
}
]
},
"test": [
{
"id": "Test1",
"name": "Create",
"description": "Create, read, search, conditional create, conditional delete.",
"metadata": {
"link": [
{
"url": "http://hl7.org/implement/standards/FHIR-Develop/patient.html",
"description": "FHIR Patient"
}
],
"capability": [
{
"validated": true,
"description": "Patient Search Operation",
"link": [
"http://hl7.org/implement/standards/FHIR-Develop/http.html#search"
],
"conformance": {
"reference": "Conformance/example"
}
}
]
},
"action": [
{
"fhir_comments": [
" Create the patient using fixture "
],
"operation": {
"type": {
"code": "create"
},
"sourceId": "example-patient"
}
},
{
"assert": {
"responseCode": "201"
}
},
{
"fhir_comments": [
" Patient search by name. Save the responseBody in 'F1' fixture.\n\t\t\t\tSave the responseHeader in H1 "
],
"operation": {
"type": {
"code": "search"
},
"resource": "Patient",
"contentType": "json",
"params": "?given=John&family=Doe",
"responseId": "R1"
}
},
{
"fhir_comments": [
" Verify that the Location in response-header is valid "
],
"assert": {
"headerField": "Location",
"operator": "notEmpty",
"warningOnly": true
}
},
{
"fhir_comments": [
" Verify that the birthdate got persisted and is being returned properly "
],
"assert": {
"operator": "equals",
"path": "fhir:Patient/fhir:birthDate/@value",
"sourceId": "R1",
"value": "1974-12-31"
}
},
{
"fhir_comments": [
" Verify that the navigation links are valid "
],
"assert": {
"navigationLinks": true,
"warningOnly": true
}
},
{
"fhir_comments": [
" Use the Location returned earlier to grab the resource\n\t\t \t\tto verify that Location was pointing to correct resource. "
],
"operation": {
"type": {
"code": "search"
},
"accept": "json",
"responseId": "R2",
"url": "${V1}"
}
},
{
"assert": {
"contentType": "json"
}
},
{
"assert": {
"response": "okay"
}
},
{
"fhir_comments": [
" Search for the resource but this time using the birthdate\n\t\t\t\tas a search parameter to make sure search by birthDate works "
],
"operation": {
"type": {
"code": "search"
},
"resource": "Patient",
"accept": "json",
"params": "?given=John&family=Doe&birthdate=1974-12-31",
"responseId": "R3"
}
},
{
"assert": {
"contentType": "json"
}
},
{
"assert": {
"response": "okay"
}
},
{
"fhir_comments": [
" Verify that the birthDate matches expectations "
],
"assert": {
"compareToSourceId": "R2",
"compareToSourcePath": "fhir:Patient/fhir:birthDate/@value",
"path": "fhir:Patient/fhir:birthDate/@value",
"sourceId": "R3"
}
},
{
"fhir_comments": [
" Verify that the name matches expectations "
],
"assert": {
"path": "fhir:Patient/fhir:name/fhir:given/@value",
"sourceId": "R3",
"value": "John"
}
},
{
"fhir_comments": [
" Conditional Create "
],
"operation": {
"type": {
"code": "create"
},
"requestHeader": [
{
"field": "If-None-Exist",
"value": "Patient?given=John&Doe&birthdate=1974-12-31"
}
],
"sourceId": "F1"
}
},
{
"fhir_comments": [
" The response code of 200 verifies that the resource\n\t\t\t\talready exists and did not get created "
],
"assert": {
"responseCode": "200"
}
},
{
"fhir_comments": [
" Conditional Delete "
],
"operation": {
"type": {
"code": "delete"
},
"resource": "Patient",
"params": "?given=John&family=Doe&birthdate=1974-12-31"
}
},
{
"fhir_comments": [
" Search again and make sure the patient has been deleted.\n\t\t \t\t This time perform read by id using variable "
],
"operation": {
"type": {
"code": "read"
},
"resource": "Patient",
"params": "/${V2}"
}
},
{
"assert": {
"responseCode": "410"
}
}
]
}
]
}

View File

@ -23,6 +23,7 @@ import org.hl7.fhir.dstu3.model.Conformance.ConformanceRestComponent;
import org.hl7.fhir.dstu3.model.Conformance.ConformanceRestResourceComponent; import org.hl7.fhir.dstu3.model.Conformance.ConformanceRestResourceComponent;
import org.hl7.fhir.dstu3.model.Conformance.ConformanceRestResourceSearchParamComponent; import org.hl7.fhir.dstu3.model.Conformance.ConformanceRestResourceSearchParamComponent;
import org.hl7.fhir.instance.model.api.IBaseBundle; import org.hl7.fhir.instance.model.api.IBaseBundle;
import org.hl7.fhir.instance.model.api.IBaseConformance;
import org.hl7.fhir.instance.model.api.IBaseResource; import org.hl7.fhir.instance.model.api.IBaseResource;
import org.springframework.ui.ModelMap; import org.springframework.ui.ModelMap;
import org.springframework.validation.BindingResult; import org.springframework.validation.BindingResult;
@ -90,7 +91,20 @@ public class Controller extends BaseController {
long start = System.currentTimeMillis(); long start = System.currentTimeMillis();
try { try {
client.conformance(); Class<? extends IBaseConformance> type;
switch (getContext(theRequest).getVersion().getVersion()) {
default:
case DSTU1:
type = Conformance.class;
break;
case DSTU2:
type = ca.uhn.fhir.model.dstu2.resource.Conformance.class;
break;
case DSTU3:
type = org.hl7.fhir.dstu3.model.Conformance.class;
break;
}
client.fetchConformance().ofType(type).execute();
} catch (Exception e) { } catch (Exception e) {
returnsResource = handleClientException(client, e, theModel); returnsResource = handleClientException(client, e, theModel);
} }