add openAPI tests

This commit is contained in:
Grahame Grieve 2019-06-03 19:38:10 +10:00
parent cb843d8235
commit 766f6b55ed
12 changed files with 2411 additions and 25 deletions

View File

@ -17965,7 +17965,7 @@ public class VersionConvertor_30_40 {
if (src.hasStandardSequence())
tgt.setStandardSequence(convertCodeableConcept(src.getStandardSequence()));
if (src.hasStart())
tgt.setStart(src.getStart()));
tgt.setStart(src.getStart());
if (src.hasEnd())
tgt.setEnd(src.getEnd());
if (src.hasScore())

View File

@ -10,6 +10,8 @@ import org.hl7.fhir.r5.model.CapabilityStatement.CapabilityStatementRestResource
import org.hl7.fhir.r5.model.CapabilityStatement.ResourceInteractionComponent;
import org.hl7.fhir.r5.model.CapabilityStatement.ResourceVersionPolicy;
import org.hl7.fhir.r5.model.CapabilityStatement.RestfulCapabilityMode;
import org.hl7.fhir.r5.model.CapabilityStatement.SystemInteractionComponent;
import org.hl7.fhir.r5.model.CapabilityStatement.SystemRestfulInteraction;
import org.hl7.fhir.r5.model.CapabilityStatement.TypeRestfulInteraction;
import org.hl7.fhir.r5.model.CodeType;
import org.hl7.fhir.r5.model.ContactDetail;
@ -70,8 +72,15 @@ public class OpenApiGenerator {
}
private void generatePaths(CapabilityStatementRestComponent csr) {
generateMetadata();
for (CapabilityStatementRestResourceComponent r : csr.getResource())
generateResource(r);
if (hasOp(csr, SystemRestfulInteraction.HISTORYSYSTEM))
generateHistorySystem(csr);
if (hasOp(csr, SystemRestfulInteraction.SEARCHSYSTEM))
generateSearchSystem(csr);
if (hasOp(csr, SystemRestfulInteraction.BATCH) || hasOp(csr, SystemRestfulInteraction.TRANSACTION) )
generateBatchTransaction(csr);
}
private void generateResource(CapabilityStatementRestResourceComponent r) {
@ -79,12 +88,39 @@ public class OpenApiGenerator {
generateSearch(r);
if (hasOp(r, TypeRestfulInteraction.READ))
generateRead(r);
if (hasOp(r, TypeRestfulInteraction.VREAD))
generateVRead(r);
if (hasOp(r, TypeRestfulInteraction.UPDATE))
generateUpdate(r);
if (hasOp(r, TypeRestfulInteraction.CREATE))
generateCreate(r);
if (hasOp(r, TypeRestfulInteraction.UPDATE))
generateUpdate(r);
if (hasOp(r, TypeRestfulInteraction.PATCH))
generatePatch(r);
if (hasOp(r, TypeRestfulInteraction.DELETE))
generateDelete(r);
if (hasOp(r, TypeRestfulInteraction.HISTORYINSTANCE))
generateHistoryInstance(r);
if (hasOp(r, TypeRestfulInteraction.VREAD))
generateVRead(r);
if (hasOp(r, TypeRestfulInteraction.HISTORYTYPE))
generateHistoryType(r);
}
private void generateMetadata() {
OperationWriter op = makePathMetadata().operation("get");
op.summary("Return the server's capability statement");
op.operationId("metadata");
opOutcome(op.responses().defaultResponse());
ResponseObjectWriter resp = op.responses().httpResponse("200");
resp.description("the capbility statement");
if (isJson())
resp.content("application/fhir+json").schemaRef(specRef()+"/fhir.json.schema#/definitions/CapabilityStatement");
if (isXml())
resp.content("application/fhir+xml").schemaRef(specRef()+"/CapabilityStatement.xsd");
// parameters - but do they apply?
op.paramRef("#/Components/parameters/format");
op.paramRef("#/Components/parameters/pretty");
op.paramRef("#/Components/parameters/summary");
op.paramRef("#/Components/parameters/elements");
}
private void generateRead(CapabilityStatementRestResourceComponent r) {
@ -110,20 +146,19 @@ public class OpenApiGenerator {
private void generateSearch(CapabilityStatementRestResourceComponent r) {
OperationWriter op = makePathResType(r).operation("get");
op.summary("Search all resources based on a set of criteria");
op.summary("Search all resources of type "+r.getType()+" based on a set of criteria");
op.operationId("search"+r.getType());
opOutcome(op.responses().defaultResponse());
ResponseObjectWriter resp = op.responses().httpResponse("200");
resp.description("the resource being returned");
if (r.getVersioning() != ResourceVersionPolicy.NOVERSION)
resp.header("ETag").description("Version from Resource.meta.version as a weak ETag");
if (isJson())
resp.content("application/fhir+json").schemaRef(specRef()+"/fhir.json.schema#/definitions/Bundle");
if (isXml())
resp.content("application/fhir+xml").schemaRef(specRef()+"/Bundle.xsd");
op.paramRef("#/Components/parameters/summary");
// todo: how do we know that these apply?
op.paramRef("#/Components/parameters/format");
op.paramRef("#/Components/parameters/pretty");
op.paramRef("#/Components/parameters/summary");
op.paramRef("#/Components/parameters/elements");
for (CapabilityStatementRestResourceSearchParamComponent spc : r.getSearchParam()) {
ParameterWriter p = op.parameter(spc.getName());
@ -138,6 +173,35 @@ public class OpenApiGenerator {
}
}
private void generateSearchSystem(CapabilityStatementRestComponent csr) {
OperationWriter op = makePathSystem().operation("get");
op.summary("Search all resources of all types based on a set of criteria");
op.operationId("searchAll");
opOutcome(op.responses().defaultResponse());
ResponseObjectWriter resp = op.responses().httpResponse("200");
resp.description("the resource being returned");
if (isJson())
resp.content("application/fhir+json").schemaRef(specRef()+"/fhir.json.schema#/definitions/Bundle");
if (isXml())
resp.content("application/fhir+xml").schemaRef(specRef()+"/Bundle.xsd");
// todo: how do we know that these apply?
op.paramRef("#/Components/parameters/format");
op.paramRef("#/Components/parameters/pretty");
op.paramRef("#/Components/parameters/summary");
op.paramRef("#/Components/parameters/elements");
for (CapabilityStatementRestResourceSearchParamComponent spc : csr.getSearchParam()) {
ParameterWriter p = op.parameter(spc.getName());
p.in(ParameterLocation.query).description(spc.getDocumentation());
p.schema().type(getSchemaType(spc.getType()));
if (spc.hasDefinition()) {
SearchParameter sp = context.fetchResource(SearchParameter.class, spc.getDefinition());
if (sp != null) {
p.description(sp.getDescription());
}
}
}
}
private SchemaType getSchemaType(SearchParamType type) {
switch (type) {
// case COMPOSITE:
@ -152,6 +216,72 @@ public class OpenApiGenerator {
return null;
}
private void generateHistoryType(CapabilityStatementRestResourceComponent r) {
OperationWriter op = makePathResHistListType(r).operation("get");
op.summary("Read the past states of the resource");
op.operationId("histinst"+r.getType());
opOutcome(op.responses().defaultResponse());
ResponseObjectWriter resp = op.responses().httpResponse("200");
resp.description("the resources being returned");
if (isJson())
resp.content("application/fhir+json").schemaRef(specRef()+"/fhir.json.schema#/definitions/Bundle");
if (isXml())
resp.content("application/fhir+xml").schemaRef(specRef()+"/Bundle.xsd");
op.paramRef("#/Components/parameters/summary");
op.paramRef("#/Components/parameters/format");
op.paramRef("#/Components/parameters/pretty");
op.paramRef("#/Components/parameters/elements");
op.parameter("_count").in(ParameterLocation.query).description("The maximum number of search results on a page. The server is not bound to return the number requested, but cannot return more").schema().type(SchemaType.number);
op.parameter("_since").in(ParameterLocation.query).description("Only include resource versions that were created at or after the given instant in time").schema().type(SchemaType.dateTime);
op.parameter("_at").in(ParameterLocation.query).description("Only include resource versions that were current at some point during the time period specified in the date time value (see Search notes on date searching)").schema().type(SchemaType.dateTime);
op.parameter("_list").in(ParameterLocation.query).description("Only include resource versions that are referenced in the specified list (current list references are allowed)").schema().type(SchemaType.string);
}
private void generateHistoryInstance(CapabilityStatementRestResourceComponent r) {
OperationWriter op = makePathResHistListId(r).operation("get");
op.summary("Read the past states of the resource");
op.operationId("histinst"+r.getType());
opOutcome(op.responses().defaultResponse());
ResponseObjectWriter resp = op.responses().httpResponse("200");
resp.description("the resources being returned");
if (isJson())
resp.content("application/fhir+json").schemaRef(specRef()+"/fhir.json.schema#/definitions/Bundle");
if (isXml())
resp.content("application/fhir+xml").schemaRef(specRef()+"/Bundle.xsd");
op.paramRef("#/Components/parameters/summary");
op.paramRef("#/Components/parameters/format");
op.paramRef("#/Components/parameters/pretty");
op.paramRef("#/Components/parameters/elements");
op.parameter("_count").in(ParameterLocation.query).description("The maximum number of search results on a page. The server is not bound to return the number requested, but cannot return more").schema().type(SchemaType.number);
op.parameter("_since").in(ParameterLocation.query).description("Only include resource versions that were created at or after the given instant in time").schema().type(SchemaType.dateTime);
op.parameter("_at").in(ParameterLocation.query).description("Only include resource versions that were current at some point during the time period specified in the date time value (see Search notes on date searching)").schema().type(SchemaType.dateTime);
op.parameter("_list").in(ParameterLocation.query).description("Only include resource versions that are referenced in the specified list (current list references are allowed)").schema().type(SchemaType.string);
}
private void generateHistorySystem(CapabilityStatementRestComponent csr) {
OperationWriter op = makePathHistListSystem().operation("get");
op.summary("Read the past states of all resources");
op.operationId("histinstAll");
opOutcome(op.responses().defaultResponse());
ResponseObjectWriter resp = op.responses().httpResponse("200");
resp.description("the resources being returned");
if (isJson())
resp.content("application/fhir+json").schemaRef(specRef()+"/fhir.json.schema#/definitions/Bundle");
if (isXml())
resp.content("application/fhir+xml").schemaRef(specRef()+"/Bundle.xsd");
op.paramRef("#/Components/parameters/summary");
op.paramRef("#/Components/parameters/format");
op.paramRef("#/Components/parameters/pretty");
op.paramRef("#/Components/parameters/elements");
op.parameter("_count").in(ParameterLocation.query).description("The maximum number of search results on a page. The server is not bound to return the number requested, but cannot return more").schema().type(SchemaType.number);
op.parameter("_since").in(ParameterLocation.query).description("Only include resource versions that were created at or after the given instant in time").schema().type(SchemaType.dateTime);
op.parameter("_at").in(ParameterLocation.query).description("Only include resource versions that were current at some point during the time period specified in the date time value (see Search notes on date searching)").schema().type(SchemaType.dateTime);
op.parameter("_list").in(ParameterLocation.query).description("Only include resource versions that are referenced in the specified list (current list references are allowed)").schema().type(SchemaType.string);
}
private void generateVRead(CapabilityStatementRestResourceComponent r) {
OperationWriter op = makePathResHistId(r).operation("get");
op.summary("Read a past state of the resource");
@ -201,6 +331,47 @@ public class OpenApiGenerator {
op.paramRef("#/Components/parameters/elements");
}
private void generatePatch(CapabilityStatementRestResourceComponent r) {
OperationWriter op = makePathResId(r).operation("patch");
op.summary("Change the current state of the resource by providing a patch - a series of change commands");
op.operationId("patch"+r.getType());
RequestBodyWriter req = op.request();
req.description("The new state of the resource").required(true);
if (isJson()) {
req.content("application/json-patch+json").schemaRef(specRef()+"/fhir.json.schema#/definitions/"+r.getType());
req.content("application/fhir+json").schemaRef(specRef()+"/fhir.json.schema#/definitions/Parameters");
}
if (isXml()) {
req.content("application/xml-patch+xml").schemaRef(specRef()+"/"+r.getType()+".xsd");
req.content("application/fhir+xml").schemaRef(specRef()+"/Parameters.xsd");
}
opOutcome(op.responses().defaultResponse());
ResponseObjectWriter resp = op.responses().httpResponse("200");
resp.description("the resource being returned after being patched");
if (r.getVersioning() != ResourceVersionPolicy.NOVERSION)
resp.header("ETag").description("Version from Resource.meta.version as a weak ETag");
if (isJson())
resp.content("application/fhir+json").schemaRef(specRef()+"/fhir.json.schema#/definitions/"+r.getType());
if (isXml())
resp.content("application/fhir+xml").schemaRef(specRef()+"/"+r.getType()+".xsd");
op.paramRef("#/Components/parameters/summary");
op.paramRef("#/Components/parameters/format");
op.paramRef("#/Components/parameters/pretty");
op.paramRef("#/Components/parameters/elements");
}
private void generateDelete(CapabilityStatementRestResourceComponent r) {
OperationWriter op = makePathResId(r).operation("delete");
op.summary("Delete the resource so that it no exists (no read, search etc)");
op.operationId("delete"+r.getType());
opOutcome(op.responses().defaultResponse());
ResponseObjectWriter resp = op.responses().httpResponse("204");
resp.description("If the resource is deleted - no content is returned");
if (r.getVersioning() != ResourceVersionPolicy.NOVERSION)
resp.header("ETag").description("Version from Resource.meta.version as a weak ETag");
}
private void generateCreate(CapabilityStatementRestResourceComponent r) {
OperationWriter op = makePathRes(r).operation("put");
op.summary("Create a new resource");
@ -227,6 +398,28 @@ public class OpenApiGenerator {
op.paramRef("#/Components/parameters/elements");
}
private void generateBatchTransaction(CapabilityStatementRestComponent csr) {
OperationWriter op = makePathSystem().operation("post");
op.summary("Batch or Transaction");
op.operationId("transaction");
RequestBodyWriter req = op.request();
req.description("The batch or transaction").required(true);
if (isJson())
req.content("application/fhir+json").schemaRef(specRef()+"/fhir.json.schema#/definitions/Bundle");
if (isXml())
req.content("application/fhir+xml").schemaRef(specRef()+"/Bundle.xsd");
opOutcome(op.responses().defaultResponse());
ResponseObjectWriter resp = op.responses().httpResponse("200");
resp.description("Batch or Transaction response");
if (isJson())
resp.content("application/fhir+json").schemaRef(specRef()+"/fhir.json.schema#/definitions/Bundle");
if (isXml())
resp.content("application/fhir+xml").schemaRef(specRef()+"/Bundle.xsd");
op.paramRef("#/Components/parameters/format");
op.paramRef("#/Components/parameters/pretty");
}
private void opOutcome(ResponseObjectWriter resp) {
resp.description("Error, with details");
if (isJson())
@ -256,6 +449,20 @@ public class OpenApiGenerator {
return false;
}
public PathItemWriter makePathSystem() {
PathItemWriter p = dest.path("/");
p.summary("System level operations");
p.description("System level operations");
return p;
}
public PathItemWriter makePathMetadata() {
PathItemWriter p = dest.path("/metadata");
p.summary("Access to the Server's Capability Statement");
p.description("All FHIR Servers return a CapabilityStatement that describes what services they perform");
return p;
}
public PathItemWriter makePathRes(CapabilityStatementRestResourceComponent r) {
PathItemWriter p = dest.path("/"+r.getType());
p.summary("Manager for resources of type "+r.getType());
@ -277,13 +484,42 @@ public class OpenApiGenerator {
return p;
}
public PathItemWriter makePathResHistId(CapabilityStatementRestResourceComponent r) {
PathItemWriter p = dest.path("/"+r.getType()+"/{rid}/_history/{hid}");
public PathItemWriter makePathResHistListType(CapabilityStatementRestResourceComponent r) {
PathItemWriter p = dest.path("/"+r.getType()+"/_history");
p.summary("Read past versions of resources of type "+r.getType());
p.description("Access to previous versions of resourcez of type "+r.getType());
return p;
}
public PathItemWriter makePathResHistListId(CapabilityStatementRestResourceComponent r) {
PathItemWriter p = dest.path("/"+r.getType()+"/{rid}/_history");
p.summary("Read past versions of resource instance of type "+r.getType());
p.description("Access to previous versions of a single resource of type "+r.getType());
return p;
}
public PathItemWriter makePathResHistId(CapabilityStatementRestResourceComponent r) {
PathItemWriter p = dest.path("/"+r.getType()+"/{rid}/_history/{hid}");
p.summary("Read a past version of resource instance of type "+r.getType());
p.description("Access a to specified previous version of a single resource of type "+r.getType());
return p;
}
public PathItemWriter makePathHistListSystem() {
PathItemWriter p = dest.path("/_history");
p.summary("Read a past version of resource instance of all types");
p.description("Access a previous versions of all types");
return p;
}
private boolean hasOp(CapabilityStatementRestComponent r, SystemRestfulInteraction opCode) {
for (SystemInteractionComponent op : r.getInteraction()) {
if (op.getCode() == opCode)
return true;
}
return false;
}
private boolean hasOp(CapabilityStatementRestResourceComponent r, TypeRestfulInteraction opCode) {
for (ResourceInteractionComponent op : r.getInteraction()) {
if (op.getCode() == opCode)

View File

@ -22,6 +22,7 @@ package org.hl7.fhir.r5.utils;
import org.hl7.fhir.r5.model.CodeableConcept;
import org.hl7.fhir.r5.model.IntegerType;
import org.hl7.fhir.r5.model.OperationOutcome;
import org.hl7.fhir.r5.model.OperationOutcome.IssueSeverity;
import org.hl7.fhir.r5.model.OperationOutcome.IssueType;
@ -40,6 +41,10 @@ public class OperationOutcomeUtilities {
s.setValue(message.getLocation()+(message.getLine()>= 0 && message.getCol() >= 0 ? " (line "+Integer.toString(message.getLine())+", col"+Integer.toString(message.getCol())+")" : "") );
issue.getLocation().add(s);
}
if (message.getLine() != 0)
issue.addExtension().setUrl(ToolingExtensions.EXT_ISSUE_LINE).setValue(new IntegerType(message.getLine()));
if (message.getCol() != 0)
issue.addExtension().setUrl(ToolingExtensions.EXT_ISSUE_COL).setValue(new IntegerType(message.getCol()));
issue.setSeverity(convert(message.getLevel()));
CodeableConcept c = new CodeableConcept();
c.setText(message.getMessage());

View File

@ -97,6 +97,8 @@ public class ToolingExtensions {
private static final String EXT_IDENTIFIER = "http://hl7.org/fhir/StructureDefinition/identifier";
public static final String EXT_TRANSLATION = "http://hl7.org/fhir/StructureDefinition/translation";
public static final String EXT_ISSUE_SOURCE = "http://hl7.org/fhir/StructureDefinition/operationoutcome-issue-source";
public static final String EXT_ISSUE_LINE = "http://hl7.org/fhir/StructureDefinition/operationoutcome-issue-line";
public static final String EXT_ISSUE_COL = "http://hl7.org/fhir/StructureDefinition/operationoutcome-issue-col";
public static final String EXT_DISPLAY_HINT = "http://hl7.org/fhir/StructureDefinition/structuredefinition-display-hint";
public static final String EXT_REPLACED_BY = "http://hl7.org/fhir/StructureDefinition/valueset-replacedby";
public static final String EXT_JSON_TYPE = "http://hl7.org/fhir/StructureDefinition/structuredefinition-json-type";

File diff suppressed because one or more lines are too long

View File

@ -0,0 +1,45 @@
{
"resourceType" : "CapabilityStatement",
"id" : "base2",
"text" : {
"status" : "generated",
"div" : "<div xmlns=\"http://www.w3.org/1999/xhtml\"><h2>Base FHIR Capability Statement (Empty)</h2><div><p>This is the base Capability Statement for FHIR. It represents a server that provides the none of the functionality defined by FHIR. It is provided to use as a template for system designers to build their own Capability Statements from. A capability statement has to contain something, so this contains a read of a Capability Statement</p>\n</div><table><tr><td>Mode</td><td>SERVER</td></tr><tr><td>Description</td><td>An empty Capability Statement</td></tr><tr><td>Transaction</td><td></td></tr><tr><td>System History</td><td></td></tr><tr><td>System Search</td><td></td></tr></table><table><tr><th><b>Resource Type</b></th><th><b>Profile</b></th><th><b title=\"GET a resource (read interaction)\">Read</b></th><th><b title=\"GET all set of resources of the type (search interaction)\">Search</b></th><th><b title=\"PUT a new resource version (update interaction)\">Update</b></th><th><b title=\"POST a new resource (create interaction)\">Create</b></th></tr><tr><td>CapabilityStatement</td><td>y</td><td></td><td></td><td></td></tr></table></div>"
},
"url" : "http://hl7.org/fhir/CapabilityStatement/base2",
"version" : "4.1.0",
"name" : "Base FHIR Capability Statement (Empty)",
"status" : "draft",
"experimental" : true,
"date" : "2019-06-01T11:22:02+10:00",
"publisher" : "FHIR Project Team",
"contact" : [{
"telecom" : [{
"system" : "url",
"value" : "http://hl7.org/fhir"
}]
}],
"description" : "This is the base Capability Statement for FHIR. It represents a server that provides the none of the functionality defined by FHIR. It is provided to use as a template for system designers to build their own Capability Statements from. A capability statement has to contain something, so this contains a read of a Capability Statement",
"kind" : "capability",
"software" : {
"name" : "Insert your software name here..."
},
"fhirVersion" : "4.1.0",
"format" : ["xml",
"json"],
"rest" : [{
"mode" : "server",
"documentation" : "An empty Capability Statement",
"security" : {
"cors" : true,
"service" : [{
"coding" : [{
"system" : "http://terminology.hl7.org/CodeSystem/restful-security-service",
"code" : "SMART-on-FHIR",
"display" : "SMART-on-FHIR"
}],
"text" : "See http://docs.smarthealthit.org/"
}],
"description" : "This is the Capability Statement to declare that the server supports SMART-on-FHIR. See the SMART-on-FHIR docs for the extension that would go with such a server"
}
}]
}

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,136 @@
{
"openapi": "3.0.2",
"info": {
"description": "This is the base Capability Statement for FHIR. It represents a server that provides the none of the functionality defined by FHIR. It is provided to use as a template for system designers to build their own Capability Statements from. A capability statement has to contain something, so this contains a read of a Capability Statement",
"license": {
"name": "test-lic",
"url": "http://spdx.org/licenses/test-lic.html"
},
"version": "4.1.0",
"contact": {
"name": "FHIR Project Team"
}
},
"externalDocs": {
"url": "http://hl7.org/fhir/CapabilityStatement/base2",
"description": "FHIR CapabilityStatement"
},
"paths": {
"/metadata": {
"summary": "Access to the Server\u0027s Capability Statement",
"description": "All FHIR Servers return a CapabilityStatement that describes what services they perform",
"get": {
"summary": "Return the server\u0027s capability statement",
"operationId": "metadata",
"responses": {
"default": {
"description": "Error, with details",
"content": {
"application/fhir+json": {
"schema": {
"$ref": "http://hl7.org/fhir/STU3/fhir.json.schema#/definitions/OperationOutcome"
}
},
"application/fhir+xml": {
"schema": {
"$ref": "http://hl7.org/fhir/STU3/OperationOutcome.xsd"
}
}
}
},
"200": {
"description": "the capbility statement",
"content": {
"application/fhir+json": {
"schema": {
"$ref": "http://hl7.org/fhir/STU3/fhir.json.schema#/definitions/CapabilityStatement"
}
},
"application/fhir+xml": {
"schema": {
"$ref": "http://hl7.org/fhir/STU3/CapabilityStatement.xsd"
}
}
}
}
},
"parameters": [
{
"$ref": "#/Components/parameters/format"
},
{
"$ref": "#/Components/parameters/pretty"
},
{
"$ref": "#/Components/parameters/summary"
},
{
"$ref": "#/Components/parameters/elements"
}
]
}
}
},
"components": {
"parameters": {
"summary": {
"summary": {
"name": "_summary",
"in": "query",
"description": "Requests the server to return a designated subset of the resource",
"allowEmptyValue": true,
"style": "matrix",
"schema": {
"type": "string",
"enum": [
"true",
"text",
"data",
"count",
"false"
]
}
}
},
"format": {
"format": {
"name": "_format",
"in": "query",
"description": "Specify alternative response formats by their MIME-types (when a client is unable acccess accept: header)",
"allowEmptyValue": true,
"style": "matrix",
"schema": {
"type": "string",
"format": "mime-type"
}
}
},
"pretty": {
"pretty": {
"name": "_pretty",
"in": "query",
"description": "Ask for a pretty printed response for human convenience",
"allowEmptyValue": true,
"style": "matrix",
"schema": {
"type": "boolean"
}
}
},
"elements": {
"elements": {
"name": "_elements",
"in": "query",
"description": "Requests the server to return a collection of elements from the resource",
"allowEmptyValue": true,
"style": "matrix",
"explode": false,
"schema": {
"type": "array",
"format": "string"
}
}
}
}
}
}

View File

@ -18,6 +18,7 @@ import org.junit.runners.Suite.SuiteClasses;
NarrativeGeneratorTests.class,
ShexGeneratorTests.class,
BaseDateTimeTypeTest.class,
OpenApiGeneratorTest.class,
SnapShotGenerationTests.class})
public class AllR5Tests {

View File

@ -0,0 +1,44 @@
package org.hl7.fhir.r5.test;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import org.hl7.fhir.exceptions.FHIRFormatError;
import org.hl7.fhir.r5.formats.JsonParser;
import org.hl7.fhir.r5.model.CapabilityStatement;
import org.hl7.fhir.r5.openapi.OpenApiGenerator;
import org.hl7.fhir.r5.openapi.Writer;
import org.hl7.fhir.r5.test.utils.TestingUtilities;
import org.hl7.fhir.utilities.xml.XMLUtil;
import org.junit.Test;
import org.w3c.dom.Document;
public class OpenApiGeneratorTest {
@Test
public void testBase1() throws IOException, FHIRFormatError {
String sfn = TestingUtilities.resourceNameToFile("openapi", "cs-base.json");
String dfn = TestingUtilities.resourceNameToFile("openapi", "swagger-base.json");
run(sfn, dfn);
}
@Test
public void testBase2() throws FHIRFormatError, FileNotFoundException, IOException {
String sfn = TestingUtilities.resourceNameToFile("openapi", "cs-base2.json");
String dfn = TestingUtilities.resourceNameToFile("openapi", "swagger-base2.json");
run(sfn, dfn);
}
public void run(String sfn, String dfn) throws IOException, FHIRFormatError, FileNotFoundException {
CapabilityStatement cs = (CapabilityStatement) new JsonParser().parse(new FileInputStream(sfn));
Writer oa = new Writer(new FileOutputStream(dfn));
OpenApiGenerator gen = new OpenApiGenerator(TestingUtilities.context(), cs, oa);
gen.generate("test-lic", "http://spdx.org/licenses/test-lic.html");
oa.commit();
}
}

View File

@ -1069,5 +1069,26 @@ public class ValidationEngine {
this.mapLog = new PrintWriter(mapLog);
}
public void prepare() {
for (StructureDefinition sd : context.allStructures()) {
try {
makeSnapshot(sd);
} catch (Exception e) {
System.out.println("Process Note: Unable to generate snapshot for "+sd.present());
}
}
}
private void makeSnapshot(StructureDefinition sd) throws DefinitionException, FHIRException {
if (sd.hasSnapshot())
return;
StructureDefinition sdb = context.fetchResource(StructureDefinition.class, sd.getBaseDefinition());
if (sdb != null) {
makeSnapshot(sdb);
new ProfileUtilities(context, null, null).generateSnapshot(sdb, sd, sd.getUrl(), null, sd.getName());
}
}
}

View File

@ -432,6 +432,7 @@ public class Validator {
System.out.println(" .. validate "+sources+" against "+profiles.toString());
else
System.out.println(" .. validate "+sources);
validator.prepare(); // generate any missing snapshots
Resource r = validator.validate(sources, profiles);
if (output == null) {
if (r instanceof Bundle)