io.vertx.ext.web.api.contract.openapi3.impl.OpenAPI3RequestValidationHandlerImpl Maven / Gradle / Ivy
package io.vertx.ext.web.api.contract.openapi3.impl;
import io.swagger.v3.oas.models.OpenAPI;
import io.swagger.v3.oas.models.Operation;
import io.swagger.v3.oas.models.media.*;
import io.swagger.v3.oas.models.parameters.Parameter;
import io.swagger.v3.oas.models.parameters.RequestBody;
import io.swagger.v3.parser.ResolverCache;
import io.vertx.ext.web.FileUpload;
import io.vertx.ext.web.RoutingContext;
import io.vertx.ext.web.api.RequestParameter;
import io.vertx.ext.web.api.contract.impl.HTTPOperationRequestValidationHandlerImpl;
import io.vertx.ext.web.api.contract.openapi3.OpenAPI3RequestValidationHandler;
import io.vertx.ext.web.api.validation.*;
import io.vertx.ext.web.api.validation.impl.*;
import io.vertx.ext.web.impl.Utils;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.regex.Pattern;
import java.util.stream.Collectors;
import static io.swagger.v3.parser.util.RefUtils.computeRefFormat;
import static io.vertx.ext.web.api.contract.openapi3.impl.OpenApi3Utils.safeBoolean;
/**
* @author Francesco Guardiani @slinkydeveloper
*/
@SuppressWarnings("rawtypes")
public class OpenAPI3RequestValidationHandlerImpl extends HTTPOperationRequestValidationHandlerImpl implements OpenAPI3RequestValidationHandler {
/* I need this class to workaround the multipart validation of content types different from json and text */
private static class MultipartCustomValidator implements CustomValidator {
Pattern contentTypePattern;
String parameterName;
boolean isOptional;
public MultipartCustomValidator(Pattern contentTypeRegex, String parameterName, boolean isOptional) {
this.contentTypePattern = contentTypeRegex;
this.parameterName = parameterName;
this.isOptional = isOptional;
}
private boolean existFileUpload(List files, String name, Pattern contentType) {
for (FileUpload f : files) {
if (f.name().equals(name) && contentType.matcher(f.contentType()).matches()) return true;
}
return false;
}
@Override
public void validate(RoutingContext routingContext) throws ValidationException {
if (!existFileUpload(routingContext.fileUploads(), parameterName, contentTypePattern)) {
if (!routingContext.request().formAttributes().contains(parameterName) && !isOptional)
throw ValidationException.ValidationExceptionFactory.generateNotFoundValidationException(parameterName,
ParameterLocation.BODY_FORM);
}
}
}
private static final ParameterTypeValidator CONTENT_TYPE_VALIDATOR = new ParameterTypeValidator() {
@Override
public RequestParameter isValid(String value) throws ValidationException {
return RequestParameter.create(value);
}
@Override
public RequestParameter isValidCollection(List value) throws ValidationException {
if (value.size() > 1) return RequestParameter.create(value);
else return this.isValid(value.get(0));
}
};
List resolvedParameters;
OpenAPI spec;
ResolverCache refsCache;
/* --- Initialization functions --- */
public OpenAPI3RequestValidationHandlerImpl(Operation pathSpec, List resolvedParameters, OpenAPI spec, ResolverCache refsCache) {
super(pathSpec);
this.resolvedParameters = resolvedParameters;
this.spec = spec;
this.refsCache = refsCache;
parseOperationSpec();
}
@Override
public void parseOperationSpec() {
// Extract from path spec parameters description
if (resolvedParameters!=null) {
for (Parameter opParameter : resolvedParameters) {
if (opParameter.get$ref() != null)
opParameter = refsCache.loadRef(opParameter.get$ref(), computeRefFormat(opParameter.get$ref()), Parameter.class);
this.parseParameter(opParameter);
}
}
RequestBody body = this.pathSpec.getRequestBody();
if (body != null) {
if (body.get$ref() != null)
body = refsCache.loadRef(body.get$ref(), computeRefFormat(body.get$ref()), RequestBody.class);
this.parseRequestBody(body);
}
}
/* --- Type parsing functions --- */
/* This function manage don't manage array, object, anyOf, oneOf, allOf. parseEnum is required for enum parsing
recursion call */
private ParameterTypeValidator resolveInnerSchemaPrimitiveTypeValidator(Schema schema, boolean parseEnum) {
if (schema == null) {
// It will never reach this
return ParameterType.GENERIC_STRING.validationMethod();
}
if (parseEnum && schema.getEnum() != null && !schema.getEnum().isEmpty()) {
return ParameterTypeValidator.createEnumTypeValidatorWithInnerValidator(
new ArrayList(schema.getEnum()),
this.resolveInnerSchemaPrimitiveTypeValidator(schema, false)
);
}
switch (schema.getType()) {
case "integer":
if (schema.getFormat() != null && schema.getFormat().equals("int64")) {
return ParameterTypeValidator.createLongTypeValidator(schema.getExclusiveMaximum(), (schema.getMaximum() !=
null) ? schema.getMaximum().doubleValue() : null, schema.getExclusiveMinimum(), (schema.getMinimum() !=
null) ? schema.getMinimum().doubleValue() : null, (schema.getMultipleOf() != null) ? schema.getMultipleOf
().doubleValue() : null, (schema.getDefault() != null) ? schema.getDefault().toString() : null);
} else {
return ParameterTypeValidator.createIntegerTypeValidator(schema.getExclusiveMaximum(), (schema.getMaximum() !=
null) ? schema.getMaximum().doubleValue() : null, schema.getExclusiveMinimum(), (schema.getMinimum() !=
null) ? schema.getMinimum().doubleValue() : null, (schema.getMultipleOf() != null) ? schema.getMultipleOf
().doubleValue() : null, (schema.getDefault() != null) ? schema.getDefault().toString() : null);
}
case "number":
if (schema.getFormat() != null && schema.getFormat().equals("float"))
return ParameterTypeValidator.createFloatTypeValidator(schema.getExclusiveMaximum(), (schema.getMaximum() !=
null) ? schema.getMaximum().doubleValue() : null, schema.getExclusiveMinimum(), (schema.getMinimum() !=
null) ? schema.getMinimum().doubleValue() : null, (schema.getMultipleOf() != null) ? schema.getMultipleOf
().doubleValue() : null, (schema.getDefault() != null) ? schema.getDefault().toString() : null);
else
return ParameterTypeValidator.createDoubleTypeValidator(schema.getExclusiveMaximum(), (schema.getMaximum()
!= null) ? schema.getMaximum().doubleValue() : null, schema.getExclusiveMinimum(), (schema.getMinimum() !=
null) ? schema.getMinimum().doubleValue() : null, (schema.getMultipleOf() != null) ? schema.getMultipleOf
().doubleValue() : null, (schema.getDefault() != null) ? schema.getDefault().toString() : null);
case "boolean":
return ParameterTypeValidator.createBooleanTypeValidator(schema.getDefault());
case "string":
String regex = null;
// Then resolve various string formats
if (schema.getFormat() != null) switch (schema.getFormat()) {
case "binary":
break;
case "byte":
regex = RegularExpressions.BASE64;
break;
case "date":
regex = RegularExpressions.DATE;
break;
case "date-time":
regex = RegularExpressions.DATETIME;
break;
case "ipv4":
regex = RegularExpressions.IPV4;
break;
case "ipv6":
regex = RegularExpressions.IPV6;
break;
case "hostname":
regex = RegularExpressions.HOSTNAME;
break;
case "email":
regex = RegularExpressions.EMAIL;
break;
case "uuid":
regex = RegularExpressions.UUID;
break;
default:
throw new SpecFeatureNotSupportedException("format " + schema.getFormat() + " not supported");
}
return ParameterTypeValidator.createStringTypeValidator((regex != null) ? regex : schema.getPattern(), schema
.getMinLength(), schema.getMaxLength(), schema.getDefault());
}
return ParameterType.GENERIC_STRING.validationMethod();
}
/* This function is an overlay for below function */
private void resolveObjectTypeFields(ObjectTypeValidator validator, Schema schema) {
Map parameters = OpenApi3Utils.solveObjectParameters(schema);
for (Map.Entry entry : parameters.entrySet()) {
validator.addField(entry.getKey(), this.resolveInnerSchemaPrimitiveTypeValidator(entry.getValue().getSchema(), true), entry.getValue().isRequired());
}
}
/* This function resolve all type validators of anyOf or oneOf type (schema) arrays. It calls the function below */
private List resolveTypeValidatorsForAnyOfOneOf(List schemas, Parameter parent) {
List result = new ArrayList<>();
for (Schema schema : schemas) {
result.add(this.resolveAnyOfOneOfTypeValidator(schema, parent));
}
return result;
}
/* This function manage a single schema of anyOf or oneOf type (schema) arrays */
private ParameterTypeValidator resolveAnyOfOneOfTypeValidator(Schema schema, Parameter parent) {
if (schema.getType().equals("array"))
return ArrayTypeValidator.ArrayTypeValidatorFactory.createArrayTypeValidator(this
.resolveInnerSchemaPrimitiveTypeValidator(schema, true), OpenApi3Utils.resolveStyle(parent), safeBoolean.apply(parent.getExplode
()), schema.getMaxItems(), schema.getMinItems());
else if (schema.getType().equals("object")) {
ObjectTypeValidator objectTypeValidator = ObjectTypeValidator.ObjectTypeValidatorFactory
.createObjectTypeValidator(OpenApi3Utils.resolveStyle(parent), safeBoolean.apply(parent.getExplode()));
resolveObjectTypeFields(objectTypeValidator, schema);
return objectTypeValidator;
}
return this.resolveInnerSchemaPrimitiveTypeValidator(schema, true);
}
/* This function check if parameter is of type oneOf, allOf, anyOf and return required type validators. It's
detached from below function to call it from "magic" workarounds functions */
private ParameterTypeValidator resolveAnyOfOneOfTypeValidator(Parameter parameter) {
ComposedSchema composedSchema;
if (parameter.getSchema() instanceof ComposedSchema) composedSchema = (ComposedSchema) parameter.getSchema();
else return null;
if (OpenApi3Utils.isAnyOfSchema(composedSchema)) {
return new AnyOfTypeValidator(this.resolveTypeValidatorsForAnyOfOneOf(new ArrayList<>(composedSchema.getAnyOf
()), parameter));
} else if (OpenApi3Utils.isOneOfSchema(composedSchema)) {
return new OneOfTypeValidator(this.resolveTypeValidatorsForAnyOfOneOf(new ArrayList<>(composedSchema.getOneOf
()), parameter));
} else return null;
}
/* Entry point for resolve type validators */
private ParameterTypeValidator resolveTypeValidator(Parameter parameter) {
ParameterTypeValidator candidate = resolveAnyOfOneOfTypeValidator(parameter);
if (candidate != null) return candidate;
else if (OpenApi3Utils.isParameterArrayType(parameter)) {
ArraySchema arraySchema = (ArraySchema) parameter.getSchema();
return ArrayTypeValidator.ArrayTypeValidatorFactory.createArrayTypeValidator(this
.resolveInnerSchemaPrimitiveTypeValidator(arraySchema.getItems(), true), OpenApi3Utils
.resolveStyle(parameter), safeBoolean.apply(parameter.getExplode()), parameter.getSchema().getMaxItems(), parameter.getSchema()
.getMinItems());
} else if (OpenApi3Utils.isParameterObjectOrAllOfType(parameter)) {
ObjectTypeValidator objectTypeValidator = ObjectTypeValidator.ObjectTypeValidatorFactory
.createObjectTypeValidator(OpenApi3Utils.resolveStyle(parameter), safeBoolean.apply(parameter.getExplode()));
resolveObjectTypeFields(objectTypeValidator, parameter.getSchema());
return objectTypeValidator;
}
return this.resolveInnerSchemaPrimitiveTypeValidator(parameter.getSchema(), true);
}
/* --- "magic" functions for workarounds (watch below for more info) --- */
// content field can support every mime type. I will use a default type validator for every content type, except
// application/json, that i can validate with JsonTypeValidator
// If content has multiple media types, I use anyOfTypeValidator to support every content type
private void handleContent(Parameter parameter) {
Content contents = parameter.getContent();
ParameterLocation location = resolveLocation(parameter.getIn());
List jsonsContents = OpenApi3Utils.extractTypesFromMediaTypesMap(contents, Utils::isJsonContentType);
if (jsonsContents.size() == 1) {
this.addRule(ParameterValidationRuleImpl.ParameterValidationRuleFactory
.createValidationRuleWithCustomTypeValidator(parameter.getName(), JsonTypeValidator.JsonTypeValidatorFactory
.createJsonTypeValidator(OpenApi3Utils.generateSanitizedJsonSchemaNode(jsonsContents.get(0).getSchema(), this.spec)),
!OpenApi3Utils.isRequiredParam(parameter), OpenApi3Utils.resolveAllowEmptyValue(parameter), location), location);
} else if (contents.size() > 1 && !jsonsContents.isEmpty()) {
// Mount anyOf
List validators =
jsonsContents.stream().map(e -> JsonTypeValidator.JsonTypeValidatorFactory
.createJsonTypeValidator(OpenApi3Utils.generateSanitizedJsonSchemaNode(e.getSchema(), this.spec))).collect(Collectors.toList());
validators.add(CONTENT_TYPE_VALIDATOR);
AnyOfTypeValidator validator = new AnyOfTypeValidator(validators);
this.addRule(ParameterValidationRuleImpl.ParameterValidationRuleFactory
.createValidationRuleWithCustomTypeValidator(parameter.getName(), validator, !OpenApi3Utils.isRequiredParam(parameter), OpenApi3Utils.resolveAllowEmptyValue(parameter)
, location), location);
} else {
this.addRule(ParameterValidationRuleImpl.ParameterValidationRuleFactory
.createValidationRuleWithCustomTypeValidator(parameter.getName(), CONTENT_TYPE_VALIDATOR, !OpenApi3Utils.isRequiredParam(parameter),
OpenApi3Utils.resolveAllowEmptyValue(parameter), location), location);
}
}
private void magicParameterExplodedMatrixArray(Parameter parameter) {
ParameterTypeValidator validator = ArrayTypeValidator.ArrayTypeValidatorFactory.createArrayTypeValidator(this
.resolveInnerSchemaPrimitiveTypeValidator(((ArraySchema) parameter.getSchema()).getItems(), true), "matrix_exploded_array", true, parameter.getSchema().getMaxItems(), parameter.getSchema()
.getMinItems());
this.addPathParamRule(ParameterValidationRuleImpl.ParameterValidationRuleFactory
.createValidationRuleWithCustomTypeValidator(parameter.getName(), validator, OpenApi3Utils.isRequiredParam(parameter), false, ParameterLocation.PATH));
}
private void magicParameterExplodedObject(Parameter parameter) {
Map properties = OpenApi3Utils.solveObjectParameters(parameter.getSchema());
for (Map.Entry entry : properties.entrySet()) {
if ("query".equals(parameter.getIn())) {
this.addQueryParamRule(ParameterValidationRuleImpl.ParameterValidationRuleFactory
.createValidationRuleWithCustomTypeValidator(entry.getKey(), new ExpandedObjectFieldValidator(this
.resolveInnerSchemaPrimitiveTypeValidator(entry.getValue().getSchema(), true), parameter.getName(), entry.getKey()), !entry.getValue().isRequired(), OpenApi3Utils.resolveAllowEmptyValue(parameter), ParameterLocation.QUERY));
} else if ("cookie".equals(parameter.getIn())) {
this.addCookieParamRule(ParameterValidationRuleImpl.ParameterValidationRuleFactory
.createValidationRuleWithCustomTypeValidator(entry.getKey(), new ExpandedObjectFieldValidator(this
.resolveInnerSchemaPrimitiveTypeValidator(entry.getValue().getSchema(), true), parameter.getName(), entry.getKey()), !entry.getValue().isRequired(), false, ParameterLocation.COOKIE));
} else if ("path".equals(parameter.getIn())) {
this.addPathParamRule(ParameterValidationRuleImpl.ParameterValidationRuleFactory
.createValidationRuleWithCustomTypeValidator(entry.getKey(), new ExpandedObjectFieldValidator(this
.resolveInnerSchemaPrimitiveTypeValidator(entry.getValue().getSchema(), true), parameter.getName(), entry.getKey()), !entry.getValue().isRequired(), false, ParameterLocation.PATH));
} else {
throw new SpecFeatureNotSupportedException("combination of style, type and location (in) of parameter fields " +
"" + "not supported for parameter " + parameter.getName());
}
}
if (parameter.getSchema().getAdditionalProperties() instanceof Schema) {
if ("query".equals(parameter.getIn())) {
this.setQueryAdditionalPropertyHandler(
this.resolveInnerSchemaPrimitiveTypeValidator((Schema)parameter.getSchema().getAdditionalProperties(), true),
parameter.getName()
);
} else if ("cookie".equals(parameter.getIn())) {
this.setCookieAdditionalPropertyHandler(
this.resolveInnerSchemaPrimitiveTypeValidator((Schema)parameter.getSchema().getAdditionalProperties(), true),
parameter.getName()
);
} else {
throw new SpecFeatureNotSupportedException("additionalProperties with exploded object fields not supports in path parameter " + parameter.getName());
}
}
}
private void magicParameterExplodedStyleSimpleTypeObject(Parameter parameter) {
ObjectTypeValidator objectTypeValidator = ObjectTypeValidator.ObjectTypeValidatorFactory
.createObjectTypeValidator(ContainerSerializationStyle.simple_exploded_object, false);
this.resolveObjectTypeFields(objectTypeValidator, parameter.getSchema());
switch (parameter.getIn()) {
case "path":
this.addPathParamRule(ParameterValidationRuleImpl.ParameterValidationRuleFactory
.createValidationRuleWithCustomTypeValidator(parameter.getName(), objectTypeValidator, !OpenApi3Utils
.isRequiredParam(parameter), OpenApi3Utils.resolveAllowEmptyValue(parameter), ParameterLocation.PATH));
break;
case "header":
this.addHeaderParamRule(ParameterValidationRuleImpl.ParameterValidationRuleFactory
.createValidationRuleWithCustomTypeValidator(parameter.getName(), objectTypeValidator, !OpenApi3Utils
.isRequiredParam(parameter), OpenApi3Utils.resolveAllowEmptyValue(parameter), ParameterLocation.HEADER));
break;
default:
throw new SpecFeatureNotSupportedException("combination of style, type and location (in) of parameter fields "
+ "not supported for parameter " + parameter.getName());
}
}
private void magicParameterExplodedStyleDeepObjectTypeObject(Parameter parameter) {
Map properties = OpenApi3Utils.solveObjectParameters(parameter.getSchema());
for (Map.Entry entry : properties.entrySet()) {
if (parameter.getIn().equals("query")) {
this.addQueryParamRule(ParameterValidationRuleImpl.ParameterValidationRuleFactory
.createValidationRuleWithCustomTypeValidator(parameter.getName() + "[" + entry.getKey() + "]", new ExpandedObjectFieldValidator(this
.resolveInnerSchemaPrimitiveTypeValidator(entry.getValue().getSchema(), true), parameter.getName(), entry.getKey()), !entry.getValue().isRequired(), OpenApi3Utils.resolveAllowEmptyValue(parameter), ParameterLocation.QUERY));
} else {
throw new SpecFeatureNotSupportedException("combination of style, type and location (in) of parameter fields " +
"" + "not supported for parameter " + parameter.getName());
}
}
}
/* This function check if a parameter has some particular configurations and run the needed flow to adapt it to
vertx-web validation framework
* Included not supported throws:
* - allowReserved field (it will never be supported)
* - cookie parameter with explode: true
* Included workarounds (handled in "magic" functions):
* - content
* - exploded: true & style: form & type: object or allOf -> magicParameterExplodedStyleFormTypeObject
* - exploded: true & style: simple & type: object or allOf -> magicParameterExplodedStyleSimpleTypeObject
* - exploded: true & style: deepObject & type: object or allOf -> magicParameterExplodedStyleDeepObjectTypeObject
* */
private boolean checkSupportedAndNeedWorkaround(Parameter parameter) {
boolean result = false;
if (Boolean.TRUE.equals(parameter.getAllowReserved())) {
throw new SpecFeatureNotSupportedException("allowReserved field not supported!");
} else if (parameter.getContent() != null && parameter.getContent().size() != 0) {
handleContent(parameter);
result = true;
} else /* From this moment only astonishing magic happens */ if (Boolean.TRUE.equals(parameter.getExplode())) {
boolean isObject = OpenApi3Utils.isParameterObjectOrAllOfType(parameter);
String style = OpenApi3Utils.resolveStyle(parameter);
if (OpenApi3Utils.isParameterArrayType(parameter) && "matrix".equals(style)) {
this.magicParameterExplodedMatrixArray(parameter);
result = true;
}
if (isObject && ("form".equals(style) || "matrix".equals(style) || "label".equals(style))) {
this.magicParameterExplodedObject(parameter);
result = true;
}
if (isObject && "simple".equals(style)) {
this.magicParameterExplodedStyleSimpleTypeObject(parameter);
result = true;
} else if ("deepObject".equals(style)) {
this.magicParameterExplodedStyleDeepObjectTypeObject(parameter);
result = true;
}
}
return result;
}
/* Function to resolve ParameterLocation from in string */
private ParameterLocation resolveLocation(String in) {
switch (in) {
case "header":
return ParameterLocation.HEADER;
case "query":
return ParameterLocation.QUERY;
case "cookie":
return ParameterLocation.COOKIE;
case "path":
return ParameterLocation.PATH;
default:
throw new SpecFeatureNotSupportedException("in field wrong or not supported");
}
}
/* Entry point for parse Parameter object */
private void parseParameter(Parameter parameter) {
if (!checkSupportedAndNeedWorkaround(parameter)) {
ParameterLocation location = resolveLocation(parameter.getIn());
this.addRule(ParameterValidationRuleImpl.ParameterValidationRuleFactory
.createValidationRuleWithCustomTypeValidator(parameter.getName(), this.resolveTypeValidator(parameter),
!OpenApi3Utils.isRequiredParam(parameter), OpenApi3Utils.resolveAllowEmptyValue(parameter), location), location);
}
}
/* --- Request body functions. All functions below are used to parse RequestBody object --- */
/* This function resolve types for x-www-form-urlencoded. It sets all Collections styles to "csv" */
private ParameterTypeValidator resolveSchemaTypeValidatorFormEncoded(Schema schema) {
if (schema.getType().equals("array"))
return ArrayTypeValidator.ArrayTypeValidatorFactory.createArrayTypeValidator(this
.resolveInnerSchemaPrimitiveTypeValidator(((ArraySchema) schema).getItems(), true), "csv", false, schema.getMaxItems(),
schema.getMinItems());
else if (OpenApi3Utils.isSchemaObjectOrAllOfType(schema)) {
ObjectTypeValidator objectTypeValidator = ObjectTypeValidator.ObjectTypeValidatorFactory
.createObjectTypeValidator("csv", false);
resolveObjectTypeFields(objectTypeValidator, schema);
return objectTypeValidator;
}
return this.resolveInnerSchemaPrimitiveTypeValidator(schema, true);
}
/* This function handle all multimaps parameters */
private void handleMultimapParameter(String parameterName, String contentTypeRegex, Schema schema, Schema multipartObjectSchema) {
if (contentTypeRegex == null) {
if (OpenApi3Utils.isSchemaObjectOrAllOfType(schema) || (OpenApi3Utils.isSchemaArray(schema) && OpenApi3Utils.isSchemaObjectOrAllOfType(((ArraySchema) schema).getItems()))) {
this.addFormParamRule(ParameterValidationRuleImpl.ParameterValidationRuleFactory
.createValidationRuleWithCustomTypeValidator(parameterName, JsonTypeValidator.JsonTypeValidatorFactory
.createJsonTypeValidator(OpenApi3Utils.generateSanitizedJsonSchemaNode(schema, this.spec)), !OpenApi3Utils.isRequiredParam
(multipartObjectSchema, parameterName), false, ParameterLocation.BODY_FORM));
} else if (schema.getType().equals("string") && ("binary".equals(schema.getFormat()) || "base64".equals(schema.getFormat()))) {
this.addCustomValidator(new MultipartCustomValidator(Pattern.compile(Pattern.quote("application/octet-stream")), parameterName, !OpenApi3Utils.isRequiredParam(multipartObjectSchema, parameterName)));
} else {
this.addFormParamRule(ParameterValidationRuleImpl.ParameterValidationRuleFactory
.createValidationRuleWithCustomTypeValidator(parameterName,
this.resolveSchemaTypeValidatorFormEncoded(schema),
!OpenApi3Utils.isRequiredParam(multipartObjectSchema, parameterName), false,
ParameterLocation.BODY_FORM));
}
} else {
this.addCustomValidator(new MultipartCustomValidator(Pattern.compile(contentTypeRegex), parameterName, !OpenApi3Utils.isRequiredParam(multipartObjectSchema, parameterName)));
}
}
/* Entry point for parse RequestBody object */
private void parseRequestBody(RequestBody requestBody) {
if (requestBody != null && requestBody.getContent() != null) {
for (Map.Entry mediaType : requestBody.getContent().entrySet()) {
if (Utils.isJsonContentType(mediaType.getKey()) && mediaType.getValue().getSchema() != null) {
this.setEntireBodyValidator(JsonTypeValidator.JsonTypeValidatorFactory
.createJsonTypeValidator(OpenApi3Utils.generateSanitizedJsonSchemaNode(mediaType.getValue().getSchema(), this.spec)));
} else if (mediaType.getKey().equals("application/x-www-form-urlencoded") && mediaType.getValue().getSchema()
!= null) {
for (Map.Entry paramSchema : ((Map) mediaType.getValue().getSchema().getProperties())
.entrySet()) {
this.addFormParamRule(ParameterValidationRuleImpl.ParameterValidationRuleFactory
.createValidationRuleWithCustomTypeValidator(paramSchema.getKey(), this
.resolveSchemaTypeValidatorFormEncoded(paramSchema.getValue()), !OpenApi3Utils.isRequiredParam
(mediaType.getValue().getSchema(), paramSchema.getKey()), false, ParameterLocation.BODY_FORM));
}
} else if (mediaType.getKey().equals("multipart/form-data") && mediaType.getValue().getSchema() != null &&
mediaType.getValue().getSchema().getType().equals("object")) {
for (Map.Entry multipartProperty : ((Map) mediaType.getValue().getSchema().getProperties())
.entrySet()) {
Encoding encodingProperty = null;
if (mediaType.getValue().getEncoding() != null)
encodingProperty = mediaType.getValue().getEncoding().get(multipartProperty.getKey());
String contentTypeRegex = null;
if (encodingProperty != null && encodingProperty.getContentType() != null)
contentTypeRegex = OpenApi3Utils.resolveContentTypeRegex(encodingProperty.getContentType());
handleMultimapParameter(multipartProperty.getKey(), contentTypeRegex, multipartProperty.getValue(),
mediaType.getValue().getSchema());
}
} else {
this.addBodyFileRule(mediaType.getKey());
}
}
this.bodyRequired = safeBoolean.apply(requestBody.getRequired());
}
}
}
© 2015 - 2024 Weber Informatics LLC | Privacy Policy