Test data uploader fixes
This commit is contained in:
parent
5cd13bc73f
commit
88157fe1a6
|
@ -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());
|
||||||
|
|
|
@ -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;
|
||||||
|
|
|
@ -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);
|
||||||
|
|
|
@ -84,6 +84,9 @@ public class StaleSearchDeletingSvc {
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
ourLog.info("Deleted {} searches, {} remaining", toDelete.size(), mySearchDao.count());
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -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"));
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -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>
|
||||||
|
|
|
@ -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>
|
||||||
|
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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)
|
||||||
|
|
|
@ -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;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -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);
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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&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"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
|
@ -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);
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue