Search in sources :

Example 61 with Info

use of io.swagger.v3.oas.models.info.Info in project swagger-core by swagger-api.

the class ReaderTest method testHeaderWithRef.

@Test(description = "Header with Ref")
public void testHeaderWithRef() {
    Components components = new Components();
    components.addHeaders("Header", new Header().description("Header Description"));
    OpenAPI oas = new OpenAPI().info(new Info().description("info")).components(components);
    Reader reader = new Reader(oas);
    OpenAPI openAPI = reader.read(RefHeaderResource.class);
    String yaml = "openapi: 3.0.1\n" + "info:\n" + "  description: info\n" + "paths:\n" + "  /path:\n" + "    get:\n" + "      summary: Simple get operation\n" + "      description: Defines a simple get operation with no inputs and a complex output\n" + "      operationId: getWithPayloadResponse\n" + "      responses:\n" + "        \"200\":\n" + "          description: voila!\n" + "          headers:\n" + "            Rate-Limit-Limit:\n" + "              description: The number of allowed requests in the current period\n" + "              $ref: '#/components/headers/Header'\n" + "              style: simple\n" + "              schema:\n" + "                type: integer\n" + "      deprecated: true\n" + "components:\n" + "  headers:\n" + "    Header:\n" + "      description: Header Description\n";
    SerializationMatchers.assertEqualsToYaml(openAPI, yaml);
}
Also used : Components(io.swagger.v3.oas.models.Components) Header(io.swagger.v3.oas.models.headers.Header) Info(io.swagger.v3.oas.models.info.Info) OpenAPI(io.swagger.v3.oas.models.OpenAPI) Test(org.testng.annotations.Test)

Example 62 with Info

use of io.swagger.v3.oas.models.info.Info in project swagger-core by swagger-api.

the class ReaderTest method testResponseWithRef.

@Test(description = "Responses with ref")
public void testResponseWithRef() {
    Components components = new Components();
    components.addResponses("invalidJWT", new ApiResponse().description("when JWT token invalid/expired"));
    OpenAPI oas = new OpenAPI().info(new Info().description("info")).components(components);
    Reader reader = new Reader(oas);
    OpenAPI openAPI = reader.read(RefResponsesResource.class);
    String yaml = "openapi: 3.0.1\n" + "info:\n" + "  description: info\n" + "paths:\n" + "  /:\n" + "    get:\n" + "      summary: Simple get operation\n" + "      description: Defines a simple get operation with no inputs and a complex output\n" + "        object\n" + "      operationId: getWithPayloadResponse\n" + "      responses:\n" + "        \"200\":\n" + "          description: voila!\n" + "          content:\n" + "            application/json:\n" + "              schema:\n" + "                $ref: '#/components/schemas/SampleResponseSchema'\n" + "        default:\n" + "          description: boo\n" + "          content:\n" + "            '*/*':\n" + "              schema:\n" + "                $ref: '#/components/schemas/GenericError'\n" + "        \"401\":\n" + "          $ref: '#/components/responses/invalidJWT'\n" + "      deprecated: true\n" + "components:\n" + "  schemas:\n" + "    GenericError:\n" + "      type: object\n" + "    SampleResponseSchema:\n" + "      type: object\n" + "  responses:\n" + "    invalidJWT:\n" + "      description: when JWT token invalid/expired";
    SerializationMatchers.assertEqualsToYaml(openAPI, yaml);
}
Also used : Components(io.swagger.v3.oas.models.Components) Info(io.swagger.v3.oas.models.info.Info) OpenAPI(io.swagger.v3.oas.models.OpenAPI) ApiResponse(io.swagger.v3.oas.models.responses.ApiResponse) Test(org.testng.annotations.Test)

Example 63 with Info

use of io.swagger.v3.oas.models.info.Info in project swagger-core by swagger-api.

the class SimpleBuilderTest method testBuilder.

@Test
public void testBuilder() throws Exception {
    // basic metadata
    OpenAPI oai = new OpenAPI().info(new Info().contact(new Contact().email("tony@eatbacon.org").name("Tony the Tam").url("https://foo.bar"))).externalDocs(new ExternalDocumentation().description("read more here").url("http://swagger.io")).addTagsItem(new Tag().name("funky dunky").description("all about neat things")).extensions(new HashMap<String, Object>() {

        {
            put("x-fancy-extension", "something");
        }
    });
    Map<String, Schema> schemas = new HashMap<>();
    schemas.put("StringSchema", new StringSchema().description("simple string schema").minLength(3).maxLength(100).example("it works"));
    schemas.put("IntegerSchema", new IntegerSchema().description("simple integer schema").multipleOf(new BigDecimal(3)).minimum(new BigDecimal(6)));
    oai.components(new Components().schemas(schemas));
    schemas.put("Address", new Schema().description("address object").addProperties("street", new StringSchema().description("the street number")).addProperties("city", new StringSchema().description("city")).addProperties("state", new StringSchema().description("state").minLength(2).maxLength(2)).addProperties("zip", new StringSchema().description("zip code").pattern("^\\d{5}(?:[-\\s]\\d{4})?$").minLength(2).maxLength(2)).addProperties("country", new StringSchema()._enum(new ArrayList<String>() {

        {
            this.add("US");
        }
    })).description("2-digit country code").minLength(2).maxLength(2));
    oai.paths(new Paths().addPathItem("/foo", new PathItem().description("the foo path").get(new Operation().addParametersItem(new QueryParameter().description("Records to skip").required(false).schema(new IntegerSchema())).responses(new ApiResponses().addApiResponse("200", new ApiResponse().description("it worked").content(new Content().addMediaType("application/json", new MediaType().schema(new Schema().$ref("#/components/schemas/Address")))).addLink("funky", new Link().operationId("getFunky")))))));
    System.out.println(writeJson(oai));
}
Also used : QueryParameter(io.swagger.v3.oas.models.parameters.QueryParameter) HashMap(java.util.HashMap) Schema(io.swagger.v3.oas.models.media.Schema) IntegerSchema(io.swagger.v3.oas.models.media.IntegerSchema) StringSchema(io.swagger.v3.oas.models.media.StringSchema) ArrayList(java.util.ArrayList) Operation(io.swagger.v3.oas.models.Operation) ApiResponse(io.swagger.v3.oas.models.responses.ApiResponse) Components(io.swagger.v3.oas.models.Components) PathItem(io.swagger.v3.oas.models.PathItem) ExternalDocumentation(io.swagger.v3.oas.models.ExternalDocumentation) MediaType(io.swagger.v3.oas.models.media.MediaType) StringSchema(io.swagger.v3.oas.models.media.StringSchema) Paths(io.swagger.v3.oas.models.Paths) ApiResponses(io.swagger.v3.oas.models.responses.ApiResponses) IntegerSchema(io.swagger.v3.oas.models.media.IntegerSchema) Info(io.swagger.v3.oas.models.info.Info) BigDecimal(java.math.BigDecimal) Contact(io.swagger.v3.oas.models.info.Contact) Content(io.swagger.v3.oas.models.media.Content) Tag(io.swagger.v3.oas.models.tags.Tag) OpenAPI(io.swagger.v3.oas.models.OpenAPI) Link(io.swagger.v3.oas.models.links.Link) Test(org.testng.annotations.Test)

Example 64 with Info

use of io.swagger.v3.oas.models.info.Info in project swagger-core by swagger-api.

the class SwaggerMojo method execute.

@Override
public void execute() throws MojoExecutionException, MojoFailureException {
    if (skip) {
        getLog().info("Skipping OpenAPI specification resolution");
        return;
    }
    getLog().info("Resolving OpenAPI specification..");
    if (project != null) {
        String pEnc = project.getProperties().getProperty("project.build.sourceEncoding");
        if (StringUtils.isNotBlank(pEnc)) {
            projectEncoding = pEnc;
        }
    }
    if (StringUtils.isBlank(encoding)) {
        encoding = projectEncoding;
    }
    // read swagger configuration if one was provided
    Optional<SwaggerConfiguration> swaggerConfiguration = readStructuredDataFromFile(configurationFilePath, SwaggerConfiguration.class, "configurationFilePath");
    // read openApi config, if one was provided
    Optional<OpenAPI> openAPIInput = readStructuredDataFromFile(openapiFilePath, OpenAPI.class, "openapiFilePath");
    config = mergeConfig(openAPIInput.orElse(null), swaggerConfiguration.orElse(new SwaggerConfiguration()));
    setDefaultsIfMissing(config);
    try {
        GenericOpenApiContextBuilder builder = new JaxrsOpenApiContextBuilder().openApiConfiguration(config);
        if (StringUtils.isNotBlank(contextId)) {
            builder.ctxId(contextId);
        }
        OpenApiContext context = builder.buildContext(true);
        OpenAPI openAPI = context.read();
        if (StringUtils.isNotBlank(config.getFilterClass())) {
            try {
                OpenAPISpecFilter filterImpl = (OpenAPISpecFilter) this.getClass().getClassLoader().loadClass(config.getFilterClass()).newInstance();
                SpecFilter f = new SpecFilter();
                openAPI = f.filter(openAPI, filterImpl, new HashMap<>(), new HashMap<>(), new HashMap<>());
            } catch (Exception e) {
                getLog().error("Error applying filter to API specification", e);
                throw new MojoExecutionException("Error applying filter to API specification: " + e.getMessage(), e);
            }
        }
        String openapiJson = null;
        String openapiYaml = null;
        if (Format.JSON.equals(outputFormat) || Format.JSONANDYAML.equals(outputFormat)) {
            if (config.isPrettyPrint() != null && config.isPrettyPrint()) {
                openapiJson = context.getOutputJsonMapper().writer(new DefaultPrettyPrinter()).writeValueAsString(openAPI);
            } else {
                openapiJson = context.getOutputJsonMapper().writeValueAsString(openAPI);
            }
        }
        if (Format.YAML.equals(outputFormat) || Format.JSONANDYAML.equals(outputFormat)) {
            if (config.isPrettyPrint() != null && config.isPrettyPrint()) {
                openapiYaml = context.getOutputYamlMapper().writer(new DefaultPrettyPrinter()).writeValueAsString(openAPI);
            } else {
                openapiYaml = context.getOutputYamlMapper().writeValueAsString(openAPI);
            }
        }
        Path path = Paths.get(outputPath, "temp");
        final File parentFile = path.toFile().getParentFile();
        if (parentFile != null) {
            parentFile.mkdirs();
        }
        if (openapiJson != null) {
            path = Paths.get(outputPath, outputFileName + ".json");
            Files.write(path, openapiJson.getBytes(Charset.forName(encoding)));
            getLog().info("JSON output: " + path.toFile().getCanonicalPath());
        }
        if (openapiYaml != null) {
            path = Paths.get(outputPath, outputFileName + ".yaml");
            Files.write(path, openapiYaml.getBytes(Charset.forName(encoding)));
            getLog().info("YAML output: " + path.toFile().getCanonicalPath());
        }
    } catch (OpenApiConfigurationException e) {
        getLog().error("Error resolving API specification", e);
        throw new MojoFailureException(e.getMessage(), e);
    } catch (IOException e) {
        getLog().error("Error writing API specification", e);
        throw new MojoExecutionException("Failed to write API definition", e);
    } catch (Exception e) {
        getLog().error("Error resolving API specification", e);
        throw new MojoExecutionException(e.getMessage(), e);
    }
}
Also used : DefaultPrettyPrinter(com.fasterxml.jackson.core.util.DefaultPrettyPrinter) Path(java.nio.file.Path) OpenAPISpecFilter(io.swagger.v3.core.filter.OpenAPISpecFilter) MojoExecutionException(org.apache.maven.plugin.MojoExecutionException) GenericOpenApiContextBuilder(io.swagger.v3.oas.integration.GenericOpenApiContextBuilder) OpenApiConfigurationException(io.swagger.v3.oas.integration.OpenApiConfigurationException) MojoFailureException(org.apache.maven.plugin.MojoFailureException) IOException(java.io.IOException) SwaggerConfiguration(io.swagger.v3.oas.integration.SwaggerConfiguration) IOException(java.io.IOException) MojoExecutionException(org.apache.maven.plugin.MojoExecutionException) MojoFailureException(org.apache.maven.plugin.MojoFailureException) OpenApiConfigurationException(io.swagger.v3.oas.integration.OpenApiConfigurationException) JaxrsOpenApiContextBuilder(io.swagger.v3.jaxrs2.integration.JaxrsOpenApiContextBuilder) OpenAPI(io.swagger.v3.oas.models.OpenAPI) File(java.io.File) SpecFilter(io.swagger.v3.core.filter.SpecFilter) OpenAPISpecFilter(io.swagger.v3.core.filter.OpenAPISpecFilter) OpenApiContext(io.swagger.v3.oas.integration.api.OpenApiContext)

Example 65 with Info

use of io.swagger.v3.oas.models.info.Info in project swagger-core by swagger-api.

the class Reader method read.

public OpenAPI read(Class<?> cls, String parentPath, String parentMethod, boolean isSubresource, RequestBody parentRequestBody, ApiResponses parentResponses, Set<String> parentTags, List<Parameter> parentParameters, Set<Class<?>> scannedResources) {
    Hidden hidden = cls.getAnnotation(Hidden.class);
    // class path
    final javax.ws.rs.Path apiPath = ReflectionUtils.getAnnotation(cls, javax.ws.rs.Path.class);
    if (hidden != null) {
        // || (apiPath == null && !isSubresource)) {
        return openAPI;
    }
    io.swagger.v3.oas.annotations.responses.ApiResponse[] classResponses = ReflectionUtils.getRepeatableAnnotationsArray(cls, io.swagger.v3.oas.annotations.responses.ApiResponse.class);
    List<io.swagger.v3.oas.annotations.security.SecurityScheme> apiSecurityScheme = ReflectionUtils.getRepeatableAnnotations(cls, io.swagger.v3.oas.annotations.security.SecurityScheme.class);
    List<io.swagger.v3.oas.annotations.security.SecurityRequirement> apiSecurityRequirements = ReflectionUtils.getRepeatableAnnotations(cls, io.swagger.v3.oas.annotations.security.SecurityRequirement.class);
    ExternalDocumentation apiExternalDocs = ReflectionUtils.getAnnotation(cls, ExternalDocumentation.class);
    io.swagger.v3.oas.annotations.tags.Tag[] apiTags = ReflectionUtils.getRepeatableAnnotationsArray(cls, io.swagger.v3.oas.annotations.tags.Tag.class);
    io.swagger.v3.oas.annotations.servers.Server[] apiServers = ReflectionUtils.getRepeatableAnnotationsArray(cls, io.swagger.v3.oas.annotations.servers.Server.class);
    javax.ws.rs.Consumes classConsumes = ReflectionUtils.getAnnotation(cls, javax.ws.rs.Consumes.class);
    javax.ws.rs.Produces classProduces = ReflectionUtils.getAnnotation(cls, javax.ws.rs.Produces.class);
    boolean classDeprecated = ReflectionUtils.getAnnotation(cls, Deprecated.class) != null;
    // OpenApiDefinition
    OpenAPIDefinition openAPIDefinition = ReflectionUtils.getAnnotation(cls, OpenAPIDefinition.class);
    if (openAPIDefinition != null) {
        // info
        AnnotationsUtils.getInfo(openAPIDefinition.info()).ifPresent(info -> openAPI.setInfo(info));
        // OpenApiDefinition security requirements
        SecurityParser.getSecurityRequirements(openAPIDefinition.security()).ifPresent(s -> openAPI.setSecurity(s));
        // 
        // OpenApiDefinition external docs
        AnnotationsUtils.getExternalDocumentation(openAPIDefinition.externalDocs()).ifPresent(docs -> openAPI.setExternalDocs(docs));
        // OpenApiDefinition tags
        AnnotationsUtils.getTags(openAPIDefinition.tags(), false).ifPresent(tags -> openApiTags.addAll(tags));
        // OpenApiDefinition servers
        AnnotationsUtils.getServers(openAPIDefinition.servers()).ifPresent(servers -> openAPI.setServers(servers));
        // OpenApiDefinition extensions
        if (openAPIDefinition.extensions().length > 0) {
            openAPI.setExtensions(AnnotationsUtils.getExtensions(openAPIDefinition.extensions()));
        }
    }
    // class security schemes
    if (apiSecurityScheme != null) {
        for (io.swagger.v3.oas.annotations.security.SecurityScheme securitySchemeAnnotation : apiSecurityScheme) {
            Optional<SecurityParser.SecuritySchemePair> securityScheme = SecurityParser.getSecurityScheme(securitySchemeAnnotation);
            if (securityScheme.isPresent()) {
                Map<String, SecurityScheme> securitySchemeMap = new HashMap<>();
                if (StringUtils.isNotBlank(securityScheme.get().key)) {
                    securitySchemeMap.put(securityScheme.get().key, securityScheme.get().securityScheme);
                    if (components.getSecuritySchemes() != null && components.getSecuritySchemes().size() != 0) {
                        components.getSecuritySchemes().putAll(securitySchemeMap);
                    } else {
                        components.setSecuritySchemes(securitySchemeMap);
                    }
                }
            }
        }
    }
    // class security requirements
    List<SecurityRequirement> classSecurityRequirements = new ArrayList<>();
    if (apiSecurityRequirements != null) {
        Optional<List<SecurityRequirement>> requirementsObject = SecurityParser.getSecurityRequirements(apiSecurityRequirements.toArray(new io.swagger.v3.oas.annotations.security.SecurityRequirement[apiSecurityRequirements.size()]));
        if (requirementsObject.isPresent()) {
            classSecurityRequirements = requirementsObject.get();
        }
    }
    // class tags, consider only name to add to class operations
    final Set<String> classTags = new LinkedHashSet<>();
    if (apiTags != null) {
        AnnotationsUtils.getTags(apiTags, false).ifPresent(tags -> tags.stream().map(Tag::getName).forEach(classTags::add));
    }
    // parent tags
    if (isSubresource) {
        if (parentTags != null) {
            classTags.addAll(parentTags);
        }
    }
    // servers
    final List<io.swagger.v3.oas.models.servers.Server> classServers = new ArrayList<>();
    if (apiServers != null) {
        AnnotationsUtils.getServers(apiServers).ifPresent(classServers::addAll);
    }
    // class external docs
    Optional<io.swagger.v3.oas.models.ExternalDocumentation> classExternalDocumentation = AnnotationsUtils.getExternalDocumentation(apiExternalDocs);
    JavaType classType = TypeFactory.defaultInstance().constructType(cls);
    BeanDescription bd = Json.mapper().getSerializationConfig().introspect(classType);
    final List<Parameter> globalParameters = new ArrayList<>();
    // look for constructor-level annotated properties
    globalParameters.addAll(ReaderUtils.collectConstructorParameters(cls, components, classConsumes, null));
    // look for field-level annotated properties
    globalParameters.addAll(ReaderUtils.collectFieldParameters(cls, components, classConsumes, null));
    // Make sure that the class methods are sorted for deterministic order
    // See https://docs.oracle.com/javase/8/docs/api/java/lang/Class.html#getMethods--
    final List<Method> methods = Arrays.stream(cls.getMethods()).sorted(new MethodComparator()).collect(Collectors.toList());
    // iterate class methods
    for (Method method : methods) {
        if (isOperationHidden(method)) {
            continue;
        }
        AnnotatedMethod annotatedMethod = bd.findMethod(method.getName(), method.getParameterTypes());
        javax.ws.rs.Produces methodProduces = ReflectionUtils.getAnnotation(method, javax.ws.rs.Produces.class);
        javax.ws.rs.Consumes methodConsumes = ReflectionUtils.getAnnotation(method, javax.ws.rs.Consumes.class);
        if (isMethodOverridden(method, cls)) {
            continue;
        }
        boolean methodDeprecated = ReflectionUtils.getAnnotation(method, Deprecated.class) != null;
        javax.ws.rs.Path methodPath = ReflectionUtils.getAnnotation(method, javax.ws.rs.Path.class);
        String operationPath = ReaderUtils.getPath(apiPath, methodPath, parentPath, isSubresource);
        // extending resource config.
        if (ignoreOperationPath(operationPath, parentPath) && !isSubresource) {
            continue;
        }
        Map<String, String> regexMap = new LinkedHashMap<>();
        operationPath = PathUtils.parsePath(operationPath, regexMap);
        if (operationPath != null) {
            if (config != null && ReaderUtils.isIgnored(operationPath, config)) {
                continue;
            }
            final Class<?> subResource = getSubResourceWithJaxRsSubresourceLocatorSpecs(method);
            String httpMethod = ReaderUtils.extractOperationMethod(method, OpenAPIExtensions.chain());
            httpMethod = (httpMethod == null && isSubresource) ? parentMethod : httpMethod;
            if (StringUtils.isBlank(httpMethod) && subResource == null) {
                continue;
            } else if (StringUtils.isBlank(httpMethod) && subResource != null) {
                Type returnType = method.getGenericReturnType();
                if (annotatedMethod != null && annotatedMethod.getType() != null) {
                    returnType = annotatedMethod.getType();
                }
                if (shouldIgnoreClass(returnType.getTypeName()) && !method.getGenericReturnType().equals(subResource)) {
                    continue;
                }
            }
            io.swagger.v3.oas.annotations.Operation apiOperation = ReflectionUtils.getAnnotation(method, io.swagger.v3.oas.annotations.Operation.class);
            JsonView jsonViewAnnotation;
            JsonView jsonViewAnnotationForRequestBody;
            if (apiOperation != null && apiOperation.ignoreJsonView()) {
                jsonViewAnnotation = null;
                jsonViewAnnotationForRequestBody = null;
            } else {
                jsonViewAnnotation = ReflectionUtils.getAnnotation(method, JsonView.class);
                /* If one and only one exists, use the @JsonView annotation from the method parameter annotated
                       with @RequestBody. Otherwise fall back to the @JsonView annotation for the method itself. */
                jsonViewAnnotationForRequestBody = (JsonView) Arrays.stream(ReflectionUtils.getParameterAnnotations(method)).filter(arr -> Arrays.stream(arr).anyMatch(annotation -> annotation.annotationType().equals(io.swagger.v3.oas.annotations.parameters.RequestBody.class))).flatMap(Arrays::stream).filter(annotation -> annotation.annotationType().equals(JsonView.class)).reduce((a, b) -> null).orElse(jsonViewAnnotation);
            }
            Operation operation = parseMethod(method, globalParameters, methodProduces, classProduces, methodConsumes, classConsumes, classSecurityRequirements, classExternalDocumentation, classTags, classServers, isSubresource, parentRequestBody, parentResponses, jsonViewAnnotation, classResponses, annotatedMethod);
            if (operation != null) {
                if (classDeprecated || methodDeprecated) {
                    operation.setDeprecated(true);
                }
                List<Parameter> operationParameters = new ArrayList<>();
                List<Parameter> formParameters = new ArrayList<>();
                Annotation[][] paramAnnotations = ReflectionUtils.getParameterAnnotations(method);
                if (annotatedMethod == null) {
                    // annotatedMethod not null only when method with 0-2 parameters
                    Type[] genericParameterTypes = method.getGenericParameterTypes();
                    for (int i = 0; i < genericParameterTypes.length; i++) {
                        final Type type = TypeFactory.defaultInstance().constructType(genericParameterTypes[i], cls);
                        io.swagger.v3.oas.annotations.Parameter paramAnnotation = AnnotationsUtils.getAnnotation(io.swagger.v3.oas.annotations.Parameter.class, paramAnnotations[i]);
                        Type paramType = ParameterProcessor.getParameterType(paramAnnotation, true);
                        if (paramType == null) {
                            paramType = type;
                        } else {
                            if (!(paramType instanceof Class)) {
                                paramType = type;
                            }
                        }
                        ResolvedParameter resolvedParameter = getParameters(paramType, Arrays.asList(paramAnnotations[i]), operation, classConsumes, methodConsumes, jsonViewAnnotation);
                        operationParameters.addAll(resolvedParameter.parameters);
                        // collect params to use together as request Body
                        formParameters.addAll(resolvedParameter.formParameters);
                        if (resolvedParameter.requestBody != null) {
                            processRequestBody(resolvedParameter.requestBody, operation, methodConsumes, classConsumes, operationParameters, paramAnnotations[i], type, jsonViewAnnotationForRequestBody, null);
                        }
                    }
                } else {
                    for (int i = 0; i < annotatedMethod.getParameterCount(); i++) {
                        AnnotatedParameter param = annotatedMethod.getParameter(i);
                        final Type type = TypeFactory.defaultInstance().constructType(param.getParameterType(), cls);
                        io.swagger.v3.oas.annotations.Parameter paramAnnotation = AnnotationsUtils.getAnnotation(io.swagger.v3.oas.annotations.Parameter.class, paramAnnotations[i]);
                        Type paramType = ParameterProcessor.getParameterType(paramAnnotation, true);
                        if (paramType == null) {
                            paramType = type;
                        } else {
                            if (!(paramType instanceof Class)) {
                                paramType = type;
                            }
                        }
                        ResolvedParameter resolvedParameter = getParameters(paramType, Arrays.asList(paramAnnotations[i]), operation, classConsumes, methodConsumes, jsonViewAnnotation);
                        operationParameters.addAll(resolvedParameter.parameters);
                        // collect params to use together as request Body
                        formParameters.addAll(resolvedParameter.formParameters);
                        if (resolvedParameter.requestBody != null) {
                            processRequestBody(resolvedParameter.requestBody, operation, methodConsumes, classConsumes, operationParameters, paramAnnotations[i], type, jsonViewAnnotationForRequestBody, null);
                        }
                    }
                }
                // if we have form parameters, need to merge them into single schema and use as request body..
                if (!formParameters.isEmpty()) {
                    Schema mergedSchema = new ObjectSchema();
                    Map<String, Encoding> encoding = new LinkedHashMap<>();
                    for (Parameter formParam : formParameters) {
                        if (formParam.getExplode() != null || (formParam.getStyle() != null) && Encoding.StyleEnum.fromString(formParam.getStyle().toString()) != null) {
                            Encoding e = new Encoding();
                            if (formParam.getExplode() != null) {
                                e.explode(formParam.getExplode());
                            }
                            if (formParam.getStyle() != null && Encoding.StyleEnum.fromString(formParam.getStyle().toString()) != null) {
                                e.style(Encoding.StyleEnum.fromString(formParam.getStyle().toString()));
                            }
                            encoding.put(formParam.getName(), e);
                        }
                        mergedSchema.addProperties(formParam.getName(), formParam.getSchema());
                        if (formParam.getSchema() != null && StringUtils.isNotBlank(formParam.getDescription()) && StringUtils.isBlank(formParam.getSchema().getDescription())) {
                            formParam.getSchema().description(formParam.getDescription());
                        }
                        if (null != formParam.getRequired() && formParam.getRequired()) {
                            mergedSchema.addRequiredItem(formParam.getName());
                        }
                    }
                    Parameter merged = new Parameter().schema(mergedSchema);
                    processRequestBody(merged, operation, methodConsumes, classConsumes, operationParameters, new Annotation[0], null, jsonViewAnnotationForRequestBody, encoding);
                }
                if (!operationParameters.isEmpty()) {
                    for (Parameter operationParameter : operationParameters) {
                        operation.addParametersItem(operationParameter);
                    }
                }
                // if subresource, merge parent parameters
                if (parentParameters != null) {
                    for (Parameter parentParameter : parentParameters) {
                        operation.addParametersItem(parentParameter);
                    }
                }
                if (subResource != null && !scannedResources.contains(subResource)) {
                    scannedResources.add(subResource);
                    read(subResource, operationPath, httpMethod, true, operation.getRequestBody(), operation.getResponses(), classTags, operation.getParameters(), scannedResources);
                    // remove the sub resource so that it can visit it later in another path
                    // but we have a room for optimization in the future to reuse the scanned result
                    // by caching the scanned resources in the reader instance to avoid actual scanning
                    // the the resources again
                    scannedResources.remove(subResource);
                    // don't proceed with root resource operation, as it's handled by subresource
                    continue;
                }
                final Iterator<OpenAPIExtension> chain = OpenAPIExtensions.chain();
                if (chain.hasNext()) {
                    final OpenAPIExtension extension = chain.next();
                    extension.decorateOperation(operation, method, chain);
                }
                PathItem pathItemObject;
                if (openAPI.getPaths() != null && openAPI.getPaths().get(operationPath) != null) {
                    pathItemObject = openAPI.getPaths().get(operationPath);
                } else {
                    pathItemObject = new PathItem();
                }
                if (StringUtils.isBlank(httpMethod)) {
                    continue;
                }
                setPathItemOperation(pathItemObject, httpMethod, operation);
                paths.addPathItem(operationPath, pathItemObject);
                if (openAPI.getPaths() != null) {
                    this.paths.putAll(openAPI.getPaths());
                }
                openAPI.setPaths(this.paths);
            }
        }
    }
    // if no components object is defined in openApi instance passed by client, set openAPI.components to resolved components (if not empty)
    if (!isEmptyComponents(components) && openAPI.getComponents() == null) {
        openAPI.setComponents(components);
    }
    // add tags from class to definition tags
    AnnotationsUtils.getTags(apiTags, true).ifPresent(tags -> openApiTags.addAll(tags));
    if (!openApiTags.isEmpty()) {
        Set<Tag> tagsSet = new LinkedHashSet<>();
        if (openAPI.getTags() != null) {
            for (Tag tag : openAPI.getTags()) {
                if (tagsSet.stream().noneMatch(t -> t.getName().equals(tag.getName()))) {
                    tagsSet.add(tag);
                }
            }
        }
        for (Tag tag : openApiTags) {
            if (tagsSet.stream().noneMatch(t -> t.getName().equals(tag.getName()))) {
                tagsSet.add(tag);
            }
        }
        openAPI.setTags(new ArrayList<>(tagsSet));
    }
    return openAPI;
}
Also used : LinkedHashSet(java.util.LinkedHashSet) Arrays(java.util.Arrays) JsonView(com.fasterxml.jackson.annotation.JsonView) OpenAPIExtensions(io.swagger.v3.jaxrs2.ext.OpenAPIExtensions) Produces(javax.ws.rs.Produces) ResolvedSchema(io.swagger.v3.core.converter.ResolvedSchema) Parameter(io.swagger.v3.oas.models.parameters.Parameter) LoggerFactory(org.slf4j.LoggerFactory) OpenAPIConfiguration(io.swagger.v3.oas.integration.api.OpenAPIConfiguration) SecurityRequirement(io.swagger.v3.oas.models.security.SecurityRequirement) Operation(io.swagger.v3.oas.models.Operation) Application(javax.ws.rs.core.Application) StringUtils(org.apache.commons.lang3.StringUtils) AnnotationsUtils(io.swagger.v3.core.util.AnnotationsUtils) PathUtils(io.swagger.v3.core.util.PathUtils) Consumes(javax.ws.rs.Consumes) TypeFactory(com.fasterxml.jackson.databind.type.TypeFactory) Map(java.util.Map) OpenApiReader(io.swagger.v3.oas.integration.api.OpenApiReader) BeanDescription(com.fasterxml.jackson.databind.BeanDescription) Tag(io.swagger.v3.oas.models.tags.Tag) Method(java.lang.reflect.Method) ApiResponse(io.swagger.v3.oas.models.responses.ApiResponse) SecurityScheme(io.swagger.v3.oas.models.security.SecurityScheme) Content(io.swagger.v3.oas.models.media.Content) Hidden(io.swagger.v3.oas.annotations.Hidden) MediaType(io.swagger.v3.oas.models.media.MediaType) Set(java.util.Set) RequestBody(io.swagger.v3.oas.models.parameters.RequestBody) ReaderUtils(io.swagger.v3.jaxrs2.util.ReaderUtils) Paths(io.swagger.v3.oas.models.Paths) Collectors(java.util.stream.Collectors) AnnotatedType(io.swagger.v3.core.converter.AnnotatedType) OpenAPIExtension(io.swagger.v3.jaxrs2.ext.OpenAPIExtension) ModelConverters(io.swagger.v3.core.converter.ModelConverters) List(java.util.List) OpenAPIDefinition(io.swagger.v3.oas.annotations.OpenAPIDefinition) Type(java.lang.reflect.Type) Annotation(java.lang.annotation.Annotation) Server(io.swagger.v3.oas.annotations.servers.Server) Optional(java.util.Optional) ObjectSchema(io.swagger.v3.oas.models.media.ObjectSchema) Json(io.swagger.v3.core.util.Json) ExternalDocumentation(io.swagger.v3.oas.annotations.ExternalDocumentation) HashMap(java.util.HashMap) TreeSet(java.util.TreeSet) ParameterProcessor(io.swagger.v3.core.util.ParameterProcessor) ArrayList(java.util.ArrayList) HashSet(java.util.HashSet) LinkedHashMap(java.util.LinkedHashMap) OpenAPI(io.swagger.v3.oas.models.OpenAPI) Schema(io.swagger.v3.oas.models.media.Schema) JavaType(com.fasterxml.jackson.databind.JavaType) AnnotatedMethod(com.fasterxml.jackson.databind.introspect.AnnotatedMethod) LinkedHashSet(java.util.LinkedHashSet) ApiResponses(io.swagger.v3.oas.models.responses.ApiResponses) Logger(org.slf4j.Logger) AnnotatedParameter(com.fasterxml.jackson.databind.introspect.AnnotatedParameter) Iterator(java.util.Iterator) PathItem(io.swagger.v3.oas.models.PathItem) ApplicationPath(javax.ws.rs.ApplicationPath) ContextUtils(io.swagger.v3.oas.integration.ContextUtils) Callback(io.swagger.v3.oas.models.callbacks.Callback) SwaggerConfiguration(io.swagger.v3.oas.integration.SwaggerConfiguration) ReflectionUtils(io.swagger.v3.core.util.ReflectionUtils) ParameterizedType(java.lang.reflect.ParameterizedType) Components(io.swagger.v3.oas.models.Components) Encoding(io.swagger.v3.oas.models.media.Encoding) Comparator(java.util.Comparator) Collections(java.util.Collections) Server(io.swagger.v3.oas.annotations.servers.Server) Produces(javax.ws.rs.Produces) HashMap(java.util.HashMap) LinkedHashMap(java.util.LinkedHashMap) ResolvedSchema(io.swagger.v3.core.converter.ResolvedSchema) ObjectSchema(io.swagger.v3.oas.models.media.ObjectSchema) Schema(io.swagger.v3.oas.models.media.Schema) ArrayList(java.util.ArrayList) OpenAPIExtension(io.swagger.v3.jaxrs2.ext.OpenAPIExtension) ApiResponse(io.swagger.v3.oas.models.responses.ApiResponse) LinkedHashMap(java.util.LinkedHashMap) PathItem(io.swagger.v3.oas.models.PathItem) ExternalDocumentation(io.swagger.v3.oas.annotations.ExternalDocumentation) Consumes(javax.ws.rs.Consumes) ObjectSchema(io.swagger.v3.oas.models.media.ObjectSchema) Hidden(io.swagger.v3.oas.annotations.Hidden) List(java.util.List) ArrayList(java.util.ArrayList) SecurityScheme(io.swagger.v3.oas.models.security.SecurityScheme) BeanDescription(com.fasterxml.jackson.databind.BeanDescription) Encoding(io.swagger.v3.oas.models.media.Encoding) Method(java.lang.reflect.Method) AnnotatedMethod(com.fasterxml.jackson.databind.introspect.AnnotatedMethod) JavaType(com.fasterxml.jackson.databind.JavaType) OpenAPIDefinition(io.swagger.v3.oas.annotations.OpenAPIDefinition) Collectors(java.util.stream.Collectors) ModelConverters(io.swagger.v3.core.converter.ModelConverters) AnnotatedMethod(com.fasterxml.jackson.databind.introspect.AnnotatedMethod) AnnotatedParameter(com.fasterxml.jackson.databind.introspect.AnnotatedParameter) Operation(io.swagger.v3.oas.models.Operation) JsonView(com.fasterxml.jackson.annotation.JsonView) MediaType(io.swagger.v3.oas.models.media.MediaType) AnnotatedType(io.swagger.v3.core.converter.AnnotatedType) Type(java.lang.reflect.Type) JavaType(com.fasterxml.jackson.databind.JavaType) ParameterizedType(java.lang.reflect.ParameterizedType) Parameter(io.swagger.v3.oas.models.parameters.Parameter) AnnotatedParameter(com.fasterxml.jackson.databind.introspect.AnnotatedParameter) Tag(io.swagger.v3.oas.models.tags.Tag) SecurityRequirement(io.swagger.v3.oas.models.security.SecurityRequirement)

Aggregations

Test (org.testng.annotations.Test)91 OpenAPI (io.swagger.v3.oas.models.OpenAPI)77 OpenAPIV3Parser (io.swagger.v3.parser.OpenAPIV3Parser)60 SwaggerParseResult (io.swagger.v3.parser.core.models.SwaggerParseResult)56 Info (io.swagger.v3.oas.models.info.Info)39 Schema (io.swagger.v3.oas.models.media.Schema)24 IntegerSchema (io.swagger.v3.oas.models.media.IntegerSchema)22 StringSchema (io.swagger.v3.oas.models.media.StringSchema)22 ObjectSchema (io.swagger.v3.oas.models.media.ObjectSchema)19 Components (io.swagger.v3.oas.models.Components)18 ArraySchema (io.swagger.v3.oas.models.media.ArraySchema)18 ComposedSchema (io.swagger.v3.oas.models.media.ComposedSchema)17 Parameter (io.swagger.v3.oas.models.parameters.Parameter)17 ByteArraySchema (io.swagger.v3.oas.models.media.ByteArraySchema)15 QueryParameter (io.swagger.v3.oas.models.parameters.QueryParameter)15 ParseOptions (io.swagger.v3.parser.core.models.ParseOptions)15 BinarySchema (io.swagger.v3.oas.models.media.BinarySchema)14 MapSchema (io.swagger.v3.oas.models.media.MapSchema)14 DateSchema (io.swagger.v3.oas.models.media.DateSchema)13 DateTimeSchema (io.swagger.v3.oas.models.media.DateTimeSchema)13