Search in sources :

Example 6 with Extension

use of io.swagger.v3.oas.annotations.extensions.Extension 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 7 with Extension

use of io.swagger.v3.oas.annotations.extensions.Extension 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)

Example 8 with Extension

use of io.swagger.v3.oas.annotations.extensions.Extension in project swagger-core by swagger-api.

the class Reader method getParameters.

protected ResolvedParameter getParameters(Type type, List<Annotation> annotations, Operation operation, javax.ws.rs.Consumes classConsumes, javax.ws.rs.Consumes methodConsumes, JsonView jsonViewAnnotation) {
    final Iterator<OpenAPIExtension> chain = OpenAPIExtensions.chain();
    if (!chain.hasNext()) {
        return new ResolvedParameter();
    }
    LOGGER.debug("getParameters for {}", type);
    Set<Type> typesToSkip = new HashSet<>();
    final OpenAPIExtension extension = chain.next();
    LOGGER.debug("trying extension {}", extension);
    return extension.extractParameters(annotations, type, typesToSkip, components, classConsumes, methodConsumes, true, jsonViewAnnotation, chain);
}
Also used : 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) OpenAPIExtension(io.swagger.v3.jaxrs2.ext.OpenAPIExtension) HashSet(java.util.HashSet) LinkedHashSet(java.util.LinkedHashSet)

Example 9 with Extension

use of io.swagger.v3.oas.annotations.extensions.Extension in project carbon-apimgt by wso2.

the class OAS3Parser method getOASDefinitionForPublisher.

/**
 * Update OAS definition for API Publisher
 *
 * @param api           API
 * @param oasDefinition
 * @return OAS definition
 * @throws APIManagementException throws if an error occurred
 */
@Override
public String getOASDefinitionForPublisher(API api, String oasDefinition) throws APIManagementException {
    OpenAPI openAPI = getOpenAPI(oasDefinition);
    if (openAPI.getComponents() == null) {
        openAPI.setComponents(new Components());
    }
    Map<String, SecurityScheme> securitySchemes = openAPI.getComponents().getSecuritySchemes();
    if (securitySchemes == null) {
        securitySchemes = new HashMap<>();
        openAPI.getComponents().setSecuritySchemes(securitySchemes);
    }
    SecurityScheme securityScheme = securitySchemes.get(OPENAPI_SECURITY_SCHEMA_KEY);
    if (securityScheme == null) {
        securityScheme = new SecurityScheme();
        securityScheme.setType(SecurityScheme.Type.OAUTH2);
        securitySchemes.put(OPENAPI_SECURITY_SCHEMA_KEY, securityScheme);
        List<SecurityRequirement> security = new ArrayList<SecurityRequirement>();
        SecurityRequirement secReq = new SecurityRequirement();
        secReq.addList(OPENAPI_SECURITY_SCHEMA_KEY, new ArrayList<String>());
        security.add(secReq);
        openAPI.setSecurity(security);
    }
    if (securityScheme.getFlows() == null) {
        securityScheme.setFlows(new OAuthFlows());
    }
    // setting scopes id if it is null
    // https://github.com/swagger-api/swagger-parser/issues/1202
    OAuthFlow oAuthFlow = securityScheme.getFlows().getImplicit();
    if (oAuthFlow == null) {
        oAuthFlow = new OAuthFlow();
        securityScheme.getFlows().setImplicit(oAuthFlow);
    }
    if (oAuthFlow.getScopes() == null) {
        oAuthFlow.setScopes(new Scopes());
    }
    oAuthFlow.setAuthorizationUrl(OPENAPI_DEFAULT_AUTHORIZATION_URL);
    if (api.getAuthorizationHeader() != null) {
        openAPI.addExtension(APIConstants.X_WSO2_AUTH_HEADER, api.getAuthorizationHeader());
    }
    if (api.getApiLevelPolicy() != null) {
        openAPI.addExtension(APIConstants.X_THROTTLING_TIER, api.getApiLevelPolicy());
    }
    openAPI.addExtension(APIConstants.X_WSO2_CORS, api.getCorsConfiguration());
    Object prodEndpointObj = OASParserUtil.generateOASConfigForEndpoints(api, true);
    if (prodEndpointObj != null) {
        openAPI.addExtension(APIConstants.X_WSO2_PRODUCTION_ENDPOINTS, prodEndpointObj);
    }
    Object sandEndpointObj = OASParserUtil.generateOASConfigForEndpoints(api, false);
    if (sandEndpointObj != null) {
        openAPI.addExtension(APIConstants.X_WSO2_SANDBOX_ENDPOINTS, sandEndpointObj);
    }
    openAPI.addExtension(APIConstants.X_WSO2_BASEPATH, api.getContext());
    if (api.getTransports() != null) {
        openAPI.addExtension(APIConstants.X_WSO2_TRANSPORTS, api.getTransports().split(","));
    }
    String apiSecurity = api.getApiSecurity();
    // set mutual ssl extension if enabled
    if (apiSecurity != null) {
        List<String> securityList = Arrays.asList(apiSecurity.split(","));
        if (securityList.contains(APIConstants.API_SECURITY_MUTUAL_SSL)) {
            String mutualSSLOptional = !securityList.contains(APIConstants.API_SECURITY_MUTUAL_SSL_MANDATORY) ? APIConstants.OPTIONAL : APIConstants.MANDATORY;
            openAPI.addExtension(APIConstants.X_WSO2_MUTUAL_SSL, mutualSSLOptional);
        }
    }
    // This app security is should given in resource level,
    // otherwise the default oauth2 scheme defined at each resouce level will override application securities
    JsonNode appSecurityExtension = OASParserUtil.getAppSecurity(apiSecurity);
    for (String pathKey : openAPI.getPaths().keySet()) {
        PathItem pathItem = openAPI.getPaths().get(pathKey);
        for (Map.Entry<PathItem.HttpMethod, Operation> entry : pathItem.readOperationsMap().entrySet()) {
            Operation operation = entry.getValue();
            operation.addExtension(APIConstants.X_WSO2_APP_SECURITY, appSecurityExtension);
        }
    }
    openAPI.addExtension(APIConstants.X_WSO2_RESPONSE_CACHE, OASParserUtil.getResponseCacheConfig(api.getResponseCache(), api.getCacheTimeout()));
    return Json.pretty(openAPI);
}
Also used : OAuthFlows(io.swagger.v3.oas.models.security.OAuthFlows) ArrayList(java.util.ArrayList) JsonNode(com.fasterxml.jackson.databind.JsonNode) Operation(io.swagger.v3.oas.models.Operation) Components(io.swagger.v3.oas.models.Components) PathItem(io.swagger.v3.oas.models.PathItem) OAuthFlow(io.swagger.v3.oas.models.security.OAuthFlow) Scopes(io.swagger.v3.oas.models.security.Scopes) JSONObject(org.json.simple.JSONObject) OpenAPI(io.swagger.v3.oas.models.OpenAPI) SecurityScheme(io.swagger.v3.oas.models.security.SecurityScheme) Map(java.util.Map) HashMap(java.util.HashMap) LinkedHashMap(java.util.LinkedHashMap) HttpMethod(io.swagger.models.HttpMethod) SecurityRequirement(io.swagger.v3.oas.models.security.SecurityRequirement)

Example 10 with Extension

use of io.swagger.v3.oas.annotations.extensions.Extension in project carbon-apimgt by wso2.

the class OAS3Parser method getOASDefinitionWithTierContentAwareProperty.

@Override
public String getOASDefinitionWithTierContentAwareProperty(String oasDefinition, List<String> contentAwareTiersList, String apiLevelTier) throws APIManagementException {
    OpenAPIV3Parser openAPIV3Parser = new OpenAPIV3Parser();
    SwaggerParseResult parseAttemptForV3 = openAPIV3Parser.readContents(oasDefinition, null, null);
    if (CollectionUtils.isNotEmpty(parseAttemptForV3.getMessages())) {
        log.debug("Errors found when parsing OAS definition");
    }
    OpenAPI swagger = parseAttemptForV3.getOpenAPI();
    // check if API Level tier is content aware. if so, we set a extension as a global property
    if (contentAwareTiersList.contains(apiLevelTier)) {
        swagger.addExtension(APIConstants.SWAGGER_X_THROTTLING_BANDWIDTH, true);
        // no need to check resource levels since both cannot exist at the same time.
        log.debug("API Level policy is content aware..");
        return Json.pretty(swagger);
    }
    // if api level tier exists, skip checking for resource level tiers since both cannot exist at the same time.
    if (apiLevelTier != null) {
        log.debug("API Level policy is not content aware..");
        return oasDefinition;
    } else {
        log.debug("API Level policy does not exist. Checking for resource level");
        for (Map.Entry<String, PathItem> entry : swagger.getPaths().entrySet()) {
            String path = entry.getKey();
            List<Operation> operations = swagger.getPaths().get(path).readOperations();
            for (Operation op : operations) {
                if (contentAwareTiersList.contains(op.getExtensions().get(APIConstants.SWAGGER_X_THROTTLING_TIER))) {
                    if (log.isDebugEnabled()) {
                        log.debug("API resource Level policy is content aware for operation " + op.getOperationId());
                    }
                    op.addExtension(APIConstants.SWAGGER_X_THROTTLING_BANDWIDTH, true);
                }
            }
        }
        return Json.pretty(swagger);
    }
}
Also used : PathItem(io.swagger.v3.oas.models.PathItem) SwaggerParseResult(io.swagger.v3.parser.core.models.SwaggerParseResult) Operation(io.swagger.v3.oas.models.Operation) OpenAPIV3Parser(io.swagger.v3.parser.OpenAPIV3Parser) OpenAPI(io.swagger.v3.oas.models.OpenAPI) Map(java.util.Map) HashMap(java.util.HashMap) LinkedHashMap(java.util.LinkedHashMap)

Aggregations

OpenAPI (io.swagger.v3.oas.models.OpenAPI)17 Test (org.testng.annotations.Test)11 SwaggerParseResult (io.swagger.v3.parser.core.models.SwaggerParseResult)9 Operation (io.swagger.v3.oas.models.Operation)8 HashMap (java.util.HashMap)8 LinkedHashMap (java.util.LinkedHashMap)8 Map (java.util.Map)8 PathItem (io.swagger.v3.oas.models.PathItem)7 Schema (io.swagger.v3.oas.models.media.Schema)6 Paths (io.swagger.v3.oas.models.Paths)5 ArrayList (java.util.ArrayList)5 JsonNode (com.fasterxml.jackson.databind.JsonNode)4 HttpMethod (io.swagger.models.HttpMethod)4 Components (io.swagger.v3.oas.models.Components)4 ArraySchema (io.swagger.v3.oas.models.media.ArraySchema)4 JSONObject (org.json.simple.JSONObject)4 Info (io.swagger.v3.oas.models.info.Info)3 ComposedSchema (io.swagger.v3.oas.models.media.ComposedSchema)3 IntegerSchema (io.swagger.v3.oas.models.media.IntegerSchema)3 MediaType (io.swagger.v3.oas.models.media.MediaType)3