* Update fhir version constants from 4.0.0 to 4.0.1 Yes, this means the test fails. The root cause of the failure is possibly the incorrect fhir version in org.hl7.fhir.r4/src/main/java/org/hl7/fhir/r4/model/Constants.java * fixes hapifhir/hapi-fhir#3466 Includes a POST version for every GET endpoint. Excludes non-primitive parameters from GET endpoints. For an idempotent (affectsState=false) endpoint with at least one required non-primitive parameter, only support POST Also include */_search endpoints for the Search operation.
This commit is contained in:
parent
23b593aa17
commit
ee06f900fe
|
@ -77,6 +77,9 @@ import org.hl7.fhir.r4.model.Reference;
|
|||
import org.hl7.fhir.r4.model.Resource;
|
||||
import org.hl7.fhir.r4.model.StringType;
|
||||
import org.hl7.fhir.r4.model.Type;
|
||||
import org.hl7.fhir.r4.model.OperationDefinition.OperationDefinitionParameterComponent;
|
||||
import org.hl7.fhir.r4.model.OperationDefinition.OperationParameterUse;
|
||||
import org.hl7.fhir.r4.model.codesystems.DataTypes;
|
||||
import org.thymeleaf.IEngineConfiguration;
|
||||
import org.thymeleaf.TemplateEngine;
|
||||
import org.thymeleaf.cache.AlwaysValidCacheEntryValidity;
|
||||
|
@ -98,6 +101,7 @@ import java.io.InputStream;
|
|||
import java.math.BigDecimal;
|
||||
import java.nio.charset.StandardCharsets;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.HashMap;
|
||||
import java.util.Iterator;
|
||||
import java.util.LinkedHashMap;
|
||||
|
@ -569,21 +573,8 @@ public class OpenApiInterceptor {
|
|||
|
||||
// Search
|
||||
if (typeRestfulInteractions.contains(CapabilityStatement.TypeRestfulInteraction.SEARCHTYPE)) {
|
||||
Operation operation = getPathItem(paths, "/" + resourceType, PathItem.HttpMethod.GET);
|
||||
operation.addTagsItem(resourceType);
|
||||
operation.setDescription("This is a search type");
|
||||
operation.setSummary("search-type: Search for " + resourceType + " instances");
|
||||
addFhirResourceResponse(ctx, openApi, operation, null);
|
||||
|
||||
for (CapabilityStatement.CapabilityStatementRestResourceSearchParamComponent nextSearchParam : nextResource.getSearchParam()) {
|
||||
Parameter parametersItem = new Parameter();
|
||||
operation.addParametersItem(parametersItem);
|
||||
|
||||
parametersItem.setName(nextSearchParam.getName());
|
||||
parametersItem.setIn("query");
|
||||
parametersItem.setDescription(nextSearchParam.getDocumentation());
|
||||
parametersItem.setStyle(Parameter.StyleEnum.SIMPLE);
|
||||
}
|
||||
addSearchOperation(openApi, getPathItem(paths, "/" + resourceType, PathItem.HttpMethod.GET), ctx, resourceType, nextResource);
|
||||
addSearchOperation(openApi, getPathItem(paths, "/" + resourceType + "/_search", PathItem.HttpMethod.GET), ctx, resourceType, nextResource);
|
||||
}
|
||||
|
||||
// Resource-level Operations
|
||||
|
@ -596,6 +587,24 @@ public class OpenApiInterceptor {
|
|||
return openApi;
|
||||
}
|
||||
|
||||
protected void addSearchOperation(final OpenAPI openApi, final Operation operation, final FhirContext ctx,
|
||||
final String resourceType, final CapabilityStatement.CapabilityStatementRestResourceComponent nextResource) {
|
||||
operation.addTagsItem(resourceType);
|
||||
operation.setDescription("This is a search type");
|
||||
operation.setSummary("search-type: Search for " + resourceType + " instances");
|
||||
addFhirResourceResponse(ctx, openApi, operation, null);
|
||||
|
||||
for (final CapabilityStatement.CapabilityStatementRestResourceSearchParamComponent nextSearchParam : nextResource.getSearchParam()) {
|
||||
final Parameter parametersItem = new Parameter();
|
||||
operation.addParametersItem(parametersItem);
|
||||
|
||||
parametersItem.setName(nextSearchParam.getName());
|
||||
parametersItem.setIn("query");
|
||||
parametersItem.setDescription(nextSearchParam.getDocumentation());
|
||||
parametersItem.setStyle(Parameter.StyleEnum.SIMPLE);
|
||||
}
|
||||
}
|
||||
|
||||
private Supplier<IBaseResource> patchExampleSupplier() {
|
||||
return () -> {
|
||||
Parameters example = new Parameters();
|
||||
|
@ -650,8 +659,15 @@ public class OpenApiInterceptor {
|
|||
}
|
||||
|
||||
OperationDefinition operationDefinition = toCanonicalVersion(operationDefinitionNonCanonical);
|
||||
final boolean postOnly = operationDefinition.getAffectsState()
|
||||
|| operationDefinition.getParameter().stream()
|
||||
.filter(p -> p.getUse().equals(OperationParameterUse.IN))
|
||||
.anyMatch(p -> {
|
||||
final boolean required = p.getMin() > 0;
|
||||
return required && !isPrimitive(p);
|
||||
});
|
||||
|
||||
if (!operationDefinition.getAffectsState()) {
|
||||
if (!postOnly) {
|
||||
|
||||
// GET form for non-state-affecting operations
|
||||
if (theResourceType != null) {
|
||||
|
@ -671,7 +687,7 @@ public class OpenApiInterceptor {
|
|||
}
|
||||
}
|
||||
|
||||
} else {
|
||||
}
|
||||
|
||||
// POST form for all operations
|
||||
if (theResourceType != null) {
|
||||
|
@ -693,6 +709,33 @@ public class OpenApiInterceptor {
|
|||
|
||||
}
|
||||
}
|
||||
|
||||
private static List<String> primitiveTypes = Arrays.asList(
|
||||
DataTypes.BOOLEAN.toCode(),
|
||||
DataTypes.INTEGER.toCode(),
|
||||
DataTypes.STRING.toCode(),
|
||||
DataTypes.DECIMAL.toCode(),
|
||||
DataTypes.URI.toCode(),
|
||||
DataTypes.URL.toCode(),
|
||||
DataTypes.CANONICAL.toCode(),
|
||||
DataTypes.REFERENCE.toCode(),
|
||||
DataTypes.BASE64BINARY.toCode(),
|
||||
DataTypes.INSTANT.toCode(),
|
||||
DataTypes.DATE.toCode(),
|
||||
DataTypes.DATETIME.toCode(),
|
||||
DataTypes.TIME.toCode(),
|
||||
DataTypes.CODE.toCode(),
|
||||
DataTypes.CODING.toCode(),
|
||||
DataTypes.OID.toCode(),
|
||||
DataTypes.ID.toCode(),
|
||||
DataTypes.MARKDOWN.toCode(),
|
||||
DataTypes.UNSIGNEDINT.toCode(),
|
||||
DataTypes.POSITIVEINT.toCode(),
|
||||
DataTypes.UUID.toCode()
|
||||
);
|
||||
|
||||
private static boolean isPrimitive(OperationDefinitionParameterComponent parameter) {
|
||||
return primitiveTypes.contains(parameter.getType());
|
||||
}
|
||||
|
||||
private void populateOperation(FhirContext theFhirContext, OpenAPI theOpenApi, String theResourceType, OperationDefinition theOperationDefinition, Operation theOperation, boolean theGet) {
|
||||
|
@ -704,10 +747,15 @@ public class OpenApiInterceptor {
|
|||
theOperation.setSummary(theOperationDefinition.getTitle());
|
||||
theOperation.setDescription(theOperationDefinition.getDescription());
|
||||
addFhirResourceResponse(theFhirContext, theOpenApi, theOperation, null);
|
||||
|
||||
if (theGet) {
|
||||
|
||||
for (OperationDefinition.OperationDefinitionParameterComponent nextParameter : theOperationDefinition.getParameter()) {
|
||||
if ("0".equals(nextParameter.getMax()) || !nextParameter.getUse().equals(OperationParameterUse.IN)) {
|
||||
continue;
|
||||
}
|
||||
if (!isPrimitive(nextParameter) && nextParameter.getMin() == 0) {
|
||||
continue;
|
||||
}
|
||||
Parameter parametersItem = new Parameter();
|
||||
theOperation.addParametersItem(parametersItem);
|
||||
|
||||
|
@ -733,6 +781,9 @@ public class OpenApiInterceptor {
|
|||
|
||||
Parameters exampleRequestBody = new Parameters();
|
||||
for (OperationDefinition.OperationDefinitionParameterComponent nextSearchParam : theOperationDefinition.getParameter()) {
|
||||
if ("0".equals(nextSearchParam.getMax()) || !nextSearchParam.getUse().equals(OperationParameterUse.IN)) {
|
||||
continue;
|
||||
}
|
||||
Parameters.ParametersParameterComponent param = exampleRequestBody.addParameter();
|
||||
param.setName(nextSearchParam.getName());
|
||||
String paramType = nextSearchParam.getType();
|
||||
|
|
|
@ -122,7 +122,11 @@ public class OpenApiInterceptorTest {
|
|||
assertEquals("Foo Op Short", fooOpPath.getPost().getSummary());
|
||||
|
||||
PathItem lastNPath = parsed.getPaths().get("/Observation/$lastn");
|
||||
assertNull(lastNPath.getPost());
|
||||
assertNotNull(lastNPath.getPost());
|
||||
assertEquals("LastN Description", lastNPath.getPost().getDescription());
|
||||
assertEquals("LastN Short", lastNPath.getPost().getSummary());
|
||||
assertNull(lastNPath.getPost().getParameters());
|
||||
assertNotNull(lastNPath.getPost().getRequestBody());
|
||||
assertNotNull(lastNPath.getGet());
|
||||
assertEquals("LastN Description", lastNPath.getGet().getDescription());
|
||||
assertEquals("LastN Short", lastNPath.getGet().getSummary());
|
||||
|
|
Loading…
Reference in New Issue