Search in sources :

Example 1 with Explode

use of io.swagger.v3.oas.annotations.enums.Explode in project swagger-core by swagger-api.

the class ParameterProcessor method applyAnnotations.

public static Parameter applyAnnotations(Parameter parameter, Type type, List<Annotation> annotations, Components components, String[] classTypes, String[] methodTypes, JsonView jsonViewAnnotation) {
    final AnnotationsHelper helper = new AnnotationsHelper(annotations, type);
    if (helper.isContext()) {
        return null;
    }
    if (parameter == null) {
        // consider it to be body param
        parameter = new Parameter();
    }
    // first handle schema
    List<Annotation> reworkedAnnotations = new ArrayList<>(annotations);
    Annotation paramSchemaOrArrayAnnotation = getParamSchemaAnnotation(annotations);
    if (paramSchemaOrArrayAnnotation != null) {
        reworkedAnnotations.add(paramSchemaOrArrayAnnotation);
    }
    AnnotatedType annotatedType = new AnnotatedType().type(type).resolveAsRef(true).skipOverride(true).jsonViewAnnotation(jsonViewAnnotation).ctxAnnotations(reworkedAnnotations.toArray(new Annotation[reworkedAnnotations.size()]));
    ResolvedSchema resolvedSchema = ModelConverters.getInstance().resolveAsResolvedSchema(annotatedType);
    if (resolvedSchema.schema != null) {
        parameter.setSchema(resolvedSchema.schema);
    }
    resolvedSchema.referencedSchemas.forEach(components::addSchemas);
    // handle first FormParam as it affects Explode resolving
    for (Annotation annotation : annotations) {
        if (annotation.annotationType().getName().equals("javax.ws.rs.FormParam")) {
            try {
                String name = (String) annotation.annotationType().getMethod("value").invoke(annotation);
                if (StringUtils.isNotBlank(name)) {
                    parameter.setName(name);
                }
            } catch (Exception e) {
            }
            // set temporarily to "form" to inform caller that we need to further process along other form parameters
            parameter.setIn("form");
        } else if (annotation.annotationType().getName().endsWith("FormDataParam")) {
            try {
                String name = (String) annotation.annotationType().getMethod("value").invoke(annotation);
                if (StringUtils.isNotBlank(name)) {
                    parameter.setName(name);
                }
            } catch (Exception e) {
            }
            // set temporarily to "form" to inform caller that we need to further process along other form parameters
            parameter.setIn("form");
        }
    }
    for (Annotation annotation : annotations) {
        if (annotation instanceof io.swagger.v3.oas.annotations.Parameter) {
            io.swagger.v3.oas.annotations.Parameter p = (io.swagger.v3.oas.annotations.Parameter) annotation;
            if (p.hidden()) {
                return null;
            }
            if (StringUtils.isNotBlank(p.ref())) {
                parameter = new Parameter().$ref(p.ref());
                return parameter;
            }
            if (StringUtils.isNotBlank(p.description())) {
                parameter.setDescription(p.description());
            }
            if (StringUtils.isNotBlank(p.name())) {
                parameter.setName(p.name());
            }
            if (StringUtils.isNotBlank(p.in().toString())) {
                parameter.setIn(p.in().toString());
            }
            if (StringUtils.isNotBlank(p.example())) {
                try {
                    parameter.setExample(Json.mapper().readTree(p.example()));
                } catch (IOException e) {
                    parameter.setExample(p.example());
                }
            }
            if (p.deprecated()) {
                parameter.setDeprecated(p.deprecated());
            }
            if (p.required()) {
                parameter.setRequired(p.required());
            }
            if (p.allowEmptyValue()) {
                parameter.setAllowEmptyValue(p.allowEmptyValue());
            }
            if (p.allowReserved()) {
                parameter.setAllowReserved(p.allowReserved());
            }
            Map<String, Example> exampleMap = new LinkedHashMap<>();
            if (p.examples().length == 1 && StringUtils.isBlank(p.examples()[0].name())) {
                Optional<Example> exampleOptional = AnnotationsUtils.getExample(p.examples()[0], true);
                if (exampleOptional.isPresent()) {
                    parameter.setExample(exampleOptional.get());
                }
            } else {
                for (ExampleObject exampleObject : p.examples()) {
                    AnnotationsUtils.getExample(exampleObject).ifPresent(example -> exampleMap.put(exampleObject.name(), example));
                }
            }
            if (exampleMap.size() > 0) {
                parameter.setExamples(exampleMap);
            }
            if (p.extensions().length > 0) {
                Map<String, Object> extensionMap = AnnotationsUtils.getExtensions(p.extensions());
                if (extensionMap != null && !extensionMap.isEmpty()) {
                    extensionMap.forEach(parameter::addExtension);
                }
            }
            Optional<Content> content = AnnotationsUtils.getContent(p.content(), classTypes, methodTypes, parameter.getSchema(), null, jsonViewAnnotation);
            if (content.isPresent()) {
                parameter.setContent(content.get());
                parameter.setSchema(null);
            }
            setParameterStyle(parameter, p);
            setParameterExplode(parameter, p);
        } else if (annotation.annotationType().getName().equals("javax.ws.rs.PathParam")) {
            try {
                String name = (String) annotation.annotationType().getMethod("value").invoke(annotation);
                if (StringUtils.isNotBlank(name)) {
                    parameter.setName(name);
                }
            } catch (Exception e) {
            }
        } else if (annotation.annotationType().getName().equals("javax.validation.constraints.Size")) {
            try {
                if (parameter.getSchema() == null) {
                    parameter.setSchema(new ArraySchema());
                }
                if (parameter.getSchema() instanceof ArraySchema) {
                    ArraySchema as = (ArraySchema) parameter.getSchema();
                    Integer min = (Integer) annotation.annotationType().getMethod("min").invoke(annotation);
                    if (min != null) {
                        as.setMinItems(min);
                    }
                    Integer max = (Integer) annotation.annotationType().getMethod("max").invoke(annotation);
                    if (max != null) {
                        as.setMaxItems(max);
                    }
                }
            } catch (Exception e) {
                LOGGER.error("failed on " + annotation.annotationType().getName(), e);
            }
        } else if (ModelResolver.NOT_NULL_ANNOTATIONS.contains(annotation.annotationType().getSimpleName())) {
            parameter.setRequired(true);
        }
    }
    final String defaultValue = helper.getDefaultValue();
    Schema paramSchema = parameter.getSchema();
    if (paramSchema == null) {
        if (parameter.getContent() != null && !parameter.getContent().values().isEmpty()) {
            paramSchema = parameter.getContent().values().iterator().next().getSchema();
        }
    }
    if (paramSchema != null) {
        if (paramSchema instanceof ArraySchema) {
            ArraySchema as = (ArraySchema) paramSchema;
            if (defaultValue != null) {
                as.getItems().setDefault(defaultValue);
            }
        } else {
            if (defaultValue != null) {
                paramSchema.setDefault(defaultValue);
            }
        }
    }
    return parameter;
}
Also used : ExampleObject(io.swagger.v3.oas.annotations.media.ExampleObject) ResolvedSchema(io.swagger.v3.core.converter.ResolvedSchema) ArraySchema(io.swagger.v3.oas.models.media.ArraySchema) Schema(io.swagger.v3.oas.models.media.Schema) ArrayList(java.util.ArrayList) LinkedHashMap(java.util.LinkedHashMap) ArraySchema(io.swagger.v3.oas.models.media.ArraySchema) Example(io.swagger.v3.oas.models.examples.Example) ResolvedSchema(io.swagger.v3.core.converter.ResolvedSchema) IOException(java.io.IOException) Annotation(java.lang.annotation.Annotation) IOException(java.io.IOException) AnnotatedType(io.swagger.v3.core.converter.AnnotatedType) Content(io.swagger.v3.oas.models.media.Content) Parameter(io.swagger.v3.oas.models.parameters.Parameter) ExampleObject(io.swagger.v3.oas.annotations.media.ExampleObject)

Example 2 with Explode

use of io.swagger.v3.oas.annotations.enums.Explode in project swagger-parser by swagger-api.

the class OpenAPIDeserializer method getParameter.

public Parameter getParameter(ObjectNode obj, String location, ParseResult result) {
    if (obj == null) {
        return null;
    }
    Parameter parameter = null;
    JsonNode ref = obj.get("$ref");
    if (ref != null) {
        if (ref.getNodeType().equals(JsonNodeType.STRING)) {
            parameter = new Parameter();
            String mungedRef = mungedRef(ref.textValue());
            if (mungedRef != null) {
                parameter.set$ref(mungedRef);
            } else {
                parameter.set$ref(ref.textValue());
            }
            return parameter;
        } else {
            result.invalidType(location, "$ref", "string", obj);
            return null;
        }
    }
    String l = null;
    JsonNode ln = obj.get("name");
    if (ln != null) {
        l = ln.asText();
    } else {
        l = "['unknown']";
    }
    location += ".[" + l + "]";
    String value = getString("in", obj, true, location, result);
    if (!result.isAllowEmptyStrings() && StringUtils.isBlank(value) || result.isAllowEmptyStrings() && value == null) {
        return null;
    }
    if (QUERY_PARAMETER.equals(value)) {
        parameter = new QueryParameter();
    } else if (HEADER_PARAMETER.equals(value)) {
        parameter = new HeaderParameter();
    } else if (PATH_PARAMETER.equals(value)) {
        parameter = new PathParameter();
    } else if (COOKIE_PARAMETER.equals(value)) {
        parameter = new CookieParameter();
    }
    if (parameter == null) {
        result.invalidType(location, "in", "[query|header|path|cookie]", obj);
        return null;
    }
    parameter.setIn(value);
    value = getString("name", obj, true, location, result);
    if ((result.isAllowEmptyStrings() && value != null) || (!result.isAllowEmptyStrings() && !StringUtils.isBlank(value))) {
        parameter.setName(value);
    }
    value = getString("description", obj, false, location, result);
    if ((result.isAllowEmptyStrings() && value != null) || (!result.isAllowEmptyStrings() && !StringUtils.isBlank(value))) {
        parameter.setDescription(value);
    }
    Boolean required = getBoolean("required", obj, false, location, result);
    if (required != null) {
        parameter.setRequired(required);
    } else {
        parameter.setRequired(false);
    }
    Boolean deprecated = getBoolean("deprecated", obj, false, location, result);
    if (deprecated != null) {
        parameter.setDeprecated(deprecated);
    }
    if (parameter instanceof QueryParameter) {
        Boolean allowEmptyValue = getBoolean("allowEmptyValue", obj, false, location, result);
        if (allowEmptyValue != null) {
            parameter.setAllowEmptyValue(allowEmptyValue);
        }
    }
    value = getString("style", obj, false, location, result);
    setStyle(value, parameter, location, obj, result);
    Boolean explode = getBoolean("explode", obj, false, location, result);
    if (explode != null) {
        parameter.setExplode(explode);
    } else if (StyleEnum.FORM.equals(parameter.getStyle())) {
        parameter.setExplode(Boolean.TRUE);
    } else {
        parameter.setExplode(Boolean.FALSE);
    }
    ObjectNode parameterObject = getObject("schema", obj, false, location, result);
    if (parameterObject != null) {
        parameter.setSchema(getSchema(parameterObject, String.format("%s.%s", location, "schemas"), result));
    }
    ObjectNode examplesObject = getObject("examples", obj, false, location, result);
    if (examplesObject != null) {
        parameter.setExamples(getExamples(examplesObject, String.format("%s.%s", location, "examples"), result, false));
    }
    Object example = getAnyExample("example", obj, location, result);
    if (example != null) {
        if (examplesObject != null) {
            result.warning(location, "examples already defined -- ignoring \"example\" field");
        } else {
            parameter.setExample(example instanceof NullNode ? null : example);
        }
    }
    Boolean allowReserved = getBoolean("allowReserved", obj, false, location, result);
    if (allowReserved != null) {
        parameter.setAllowReserved(allowReserved);
    }
    ObjectNode contentNode = getObject("content", obj, false, location, result);
    if (contentNode != null) {
        Content content = getContent(contentNode, String.format("%s.%s", location, "content"), result);
        if (content.size() == 0) {
            result.unsupported(location, "content with no media type", contentNode);
            result.invalid();
        } else if (content.size() > 1) {
            result.unsupported(location, "content with multiple media types", contentNode);
            result.invalid();
        } else if (parameter.getSchema() != null) {
            result.unsupported(location, "content when schema defined", contentNode);
            result.invalid();
        } else {
            parameter.setContent(content);
        }
    } else if (parameter.getSchema() == null) {
        result.missing(location, "content");
    }
    Map<String, Object> extensions = getExtensions(obj);
    if (extensions != null && extensions.size() > 0) {
        parameter.setExtensions(extensions);
    }
    Set<String> keys = getKeys(obj);
    for (String key : keys) {
        if (!PARAMETER_KEYS.contains(key) && !key.startsWith("x-")) {
            result.extra(location, key, obj.get(key));
        }
    }
    return parameter;
}
Also used : QueryParameter(io.swagger.v3.oas.models.parameters.QueryParameter) ObjectNode(com.fasterxml.jackson.databind.node.ObjectNode) JsonNode(com.fasterxml.jackson.databind.JsonNode) PathParameter(io.swagger.v3.oas.models.parameters.PathParameter) Content(io.swagger.v3.oas.models.media.Content) Parameter(io.swagger.v3.oas.models.parameters.Parameter) CookieParameter(io.swagger.v3.oas.models.parameters.CookieParameter) QueryParameter(io.swagger.v3.oas.models.parameters.QueryParameter) HeaderParameter(io.swagger.v3.oas.models.parameters.HeaderParameter) PathParameter(io.swagger.v3.oas.models.parameters.PathParameter) CookieParameter(io.swagger.v3.oas.models.parameters.CookieParameter) HeaderParameter(io.swagger.v3.oas.models.parameters.HeaderParameter) NullNode(com.fasterxml.jackson.databind.node.NullNode)

Example 3 with Explode

use of io.swagger.v3.oas.annotations.enums.Explode in project swagger-parser by swagger-api.

the class OpenAPIV3ParserTest method testIssue292WithCSVCollectionFormat.

@Test
public void testIssue292WithCSVCollectionFormat() {
    String yaml = "openapi: '3.0.0'\n" + "info:\n" + "  version: '0.0.0'\n" + "  title: nada\n" + "paths:\n" + "  /persons:\n" + "    get:\n" + "      parameters:\n" + "      - name: testParam\n" + "        in: query\n" + "        type: array\n" + "        items:\n" + "          type: string\n" + "        explode: false\n" + "      responses:\n" + "        200:\n" + "          description: Successful response";
    OpenAPIV3Parser parser = new OpenAPIV3Parser();
    SwaggerParseResult result = parser.readContents(yaml, null, null);
    OpenAPI openAPI = result.getOpenAPI();
    Parameter param = openAPI.getPaths().get("/persons").getGet().getParameters().get(0);
    QueryParameter qp = (QueryParameter) param;
    assertTrue(qp.getStyle().toString().equals("form"));
    Assert.assertFalse(qp.getExplode());
}
Also used : QueryParameter(io.swagger.v3.oas.models.parameters.QueryParameter) Parameter(io.swagger.v3.oas.models.parameters.Parameter) QueryParameter(io.swagger.v3.oas.models.parameters.QueryParameter) HeaderParameter(io.swagger.v3.oas.models.parameters.HeaderParameter) PathParameter(io.swagger.v3.oas.models.parameters.PathParameter) SwaggerParseResult(io.swagger.v3.parser.core.models.SwaggerParseResult) OpenAPIV3Parser(io.swagger.v3.parser.OpenAPIV3Parser) OpenAPI(io.swagger.v3.oas.models.OpenAPI) Test(org.testng.annotations.Test)

Example 4 with Explode

use of io.swagger.v3.oas.annotations.enums.Explode in project vertx-web by vert-x3.

the class OpenAPI3ValidationTest method testQueryOptionalFormExplodeObjectFailure.

/**
 * Test: query_optional_form_explode_object
 * Expected parameters sent:
 * color: R=100&G=200&B=150&alpha=50
 * Expected response: Validation failure
 */
@Test
public void testQueryOptionalFormExplodeObjectFailure() throws Exception {
    Operation op = testSpec.getPaths().get("/query/form/explode/object").getGet();
    OpenAPI3RequestValidationHandler validationHandler = new OpenAPI3RequestValidationHandlerImpl(op, op.getParameters(), testSpec, refsCache);
    loadHandlers("/query/form/explode/object", HttpMethod.GET, true, validationHandler, routingContext -> {
        RequestParameters params = routingContext.get("parsedParameters");
        RequestParameter colorQueryParam = params.queryParameter("color");
        assertNotNull(colorQueryParam);
        assertTrue(colorQueryParam.isObject());
        routingContext.response().setStatusCode(200).setStatusMessage("OK").putHeader("content-type", "application/json").end(((JsonObject) colorQueryParam.toJson()).encode());
    });
    String requestURI = "/query/form/explode/object?R=100&G=200&B=150&alpha=aaa";
    testRequest(HttpMethod.GET, requestURI, 400, errorMessage(ValidationException.ErrorType.NO_MATCH));
}
Also used : OpenAPI3RequestValidationHandlerImpl(io.vertx.ext.web.api.contract.openapi3.impl.OpenAPI3RequestValidationHandlerImpl) RequestParameter(io.vertx.ext.web.api.RequestParameter) Operation(io.swagger.v3.oas.models.Operation) RequestParameters(io.vertx.ext.web.api.RequestParameters) Test(org.junit.Test)

Example 5 with Explode

use of io.swagger.v3.oas.annotations.enums.Explode in project vertx-web by vert-x3.

the class OpenAPI3ValidationTest method testQueryOptionalFormExplodeObject.

/**
 * Test: query_optional_form_explode_object
 * Expected parameters sent:
 * color: R=100&G=200&B=150&alpha=50
 * Expected response: {"color":{"R":"100","G":"200","B":"150","alpha":"50"}}
 */
@Test
public void testQueryOptionalFormExplodeObject() throws Exception {
    Operation op = testSpec.getPaths().get("/query/form/explode/object").getGet();
    OpenAPI3RequestValidationHandler validationHandler = new OpenAPI3RequestValidationHandlerImpl(op, op.getParameters(), testSpec, refsCache);
    loadHandlers("/query/form/explode/object", HttpMethod.GET, false, validationHandler, routingContext -> {
        RequestParameters params = routingContext.get("parsedParameters");
        RequestParameter colorQueryParam = params.queryParameter("color");
        assertNotNull(colorQueryParam);
        assertTrue(colorQueryParam.isObject());
        routingContext.response().setStatusCode(200).setStatusMessage("OK").putHeader("content-type", "application/json").end(((JsonObject) colorQueryParam.toJson()).encode());
    });
    String requestURI = "/query/form/explode/object?R=100&G=200&B=150&alpha=50";
    testEmptyRequestWithJSONObjectResponse(HttpMethod.GET, requestURI, 200, "OK", new JsonObject("{\"R\":\"100\",\"G\":\"200\",\"B\":\"150\",\"alpha\":50}"));
}
Also used : OpenAPI3RequestValidationHandlerImpl(io.vertx.ext.web.api.contract.openapi3.impl.OpenAPI3RequestValidationHandlerImpl) RequestParameter(io.vertx.ext.web.api.RequestParameter) JsonObject(io.vertx.core.json.JsonObject) Operation(io.swagger.v3.oas.models.Operation) RequestParameters(io.vertx.ext.web.api.RequestParameters) Test(org.junit.Test)

Aggregations

Parameter (io.swagger.v3.oas.models.parameters.Parameter)6 Operation (io.swagger.v3.oas.models.Operation)5 Test (org.junit.Test)5 RequestParameter (io.vertx.ext.web.api.RequestParameter)4 RequestParameters (io.vertx.ext.web.api.RequestParameters)4 OpenAPI3RequestValidationHandlerImpl (io.vertx.ext.web.api.contract.openapi3.impl.OpenAPI3RequestValidationHandlerImpl)4 ObjectNode (com.fasterxml.jackson.databind.node.ObjectNode)3 ArraySchema (io.swagger.v3.oas.models.media.ArraySchema)3 Schema (io.swagger.v3.oas.models.media.Schema)3 Collectors (java.util.stream.Collectors)3 JsonNode (com.fasterxml.jackson.databind.JsonNode)2 NullNode (com.fasterxml.jackson.databind.node.NullNode)2 Parameter (io.swagger.v3.oas.annotations.Parameter)2 Explode (io.swagger.v3.oas.annotations.enums.Explode)2 OpenAPI (io.swagger.v3.oas.models.OpenAPI)2 Content (io.swagger.v3.oas.models.media.Content)2 ObjectSchema (io.swagger.v3.oas.models.media.ObjectSchema)2 StringSchema (io.swagger.v3.oas.models.media.StringSchema)2 HeaderParameter (io.swagger.v3.oas.models.parameters.HeaderParameter)2 PathParameter (io.swagger.v3.oas.models.parameters.PathParameter)2