Search in sources :

Example 1 with RouterOperation

use of org.springdoc.core.fn.RouterOperation in project springdoc-openapi by springdoc.

the class SpringCloudFunctionProvider method buildRouterOperation.

/**
 * Build router operation router operation.
 *
 * @param name the name
 * @param type the type
 * @param requestMethod the request method
 * @param routerOperationList the router operation list
 * @return the router operation
 */
private RouterOperation buildRouterOperation(String name, String type, RequestMethod requestMethod, List<RouterOperation> routerOperationList) {
    Operation operation = new Operation().operationId(name + "_" + requestMethod);
    RouterOperation routerOperation = new RouterOperation();
    routerOperation.setConsumes(defaultMediaTypes);
    routerOperation.setProduces(defaultMediaTypes);
    routerOperation.setMethods(new RequestMethod[] { requestMethod });
    operation.description(name + type);
    routerOperation.setOperationModel(operation);
    routerOperationList.add(routerOperation);
    return routerOperation;
}
Also used : RouterOperation(org.springdoc.core.fn.RouterOperation) Operation(io.swagger.v3.oas.models.Operation) RouterOperation(org.springdoc.core.fn.RouterOperation)

Example 2 with RouterOperation

use of org.springdoc.core.fn.RouterOperation in project springdoc-openapi by springdoc.

the class SpringCloudFunctionProvider method getRouterOperations.

@Override
public List<RouterOperation> getRouterOperations(OpenAPI openAPI) {
    List<RouterOperation> routerOperationList = new ArrayList<>();
    functionCatalogOptional.ifPresent(functionCatalog -> {
        Set<String> names = functionCatalog.getNames(null);
        for (String name : names) {
            if (!RoutingFunction.FUNCTION_NAME.equals(name)) {
                FunctionInvocationWrapper function = functionCatalog.lookup(name);
                if (function.isFunction()) {
                    for (RequestMethod requestMethod : functionRequestMethods) {
                        RouterOperation routerOperation = buildRouterOperation(name, " function", requestMethod, routerOperationList);
                        buildRequest(openAPI, name, function, requestMethod, routerOperation);
                        ApiResponses apiResponses = buildResponses(openAPI, function, defaultMediaTypes);
                        routerOperation.getOperationModel().responses(apiResponses);
                        if (StringUtils.isEmpty(prefix)) {
                            if (GET.equals(requestMethod))
                                routerOperation.setPath(AntPathMatcher.DEFAULT_PATH_SEPARATOR + name + AntPathMatcher.DEFAULT_PATH_SEPARATOR + "{" + name + "}");
                            else
                                routerOperation.setPath(AntPathMatcher.DEFAULT_PATH_SEPARATOR + name);
                        } else {
                            if (GET.equals(requestMethod))
                                routerOperation.setPath(prefix + AntPathMatcher.DEFAULT_PATH_SEPARATOR + name + AntPathMatcher.DEFAULT_PATH_SEPARATOR + "{" + name + "}");
                            else
                                routerOperation.setPath(prefix + AntPathMatcher.DEFAULT_PATH_SEPARATOR + name);
                        }
                        RouterOperation userRouterOperation = this.getRouterFunctionPaths(name, requestMethod);
                        if (userRouterOperation != null)
                            mergeRouterOperation(routerOperation, userRouterOperation);
                    }
                } else if (function.isConsumer()) {
                    for (RequestMethod requestMethod : consumerRequestMethods) {
                        RouterOperation routerOperation = buildRouterOperation(name, " consumer", requestMethod, routerOperationList);
                        buildRequest(openAPI, name, function, requestMethod, routerOperation);
                        ApiResponses apiResponses = new ApiResponses();
                        ApiResponse apiResponse = new ApiResponse();
                        apiResponse.setContent(new Content());
                        apiResponses.put(String.valueOf(HttpStatus.ACCEPTED.value()), apiResponse.description(HttpStatus.ACCEPTED.getReasonPhrase()));
                        routerOperation.getOperationModel().responses(apiResponses);
                        if (StringUtils.isEmpty(prefix))
                            routerOperation.setPath(AntPathMatcher.DEFAULT_PATH_SEPARATOR + name);
                        else
                            routerOperation.setPath(prefix + AntPathMatcher.DEFAULT_PATH_SEPARATOR + name);
                        RouterOperation userRouterOperation = this.getRouterFunctionPaths(name, requestMethod);
                        if (userRouterOperation != null)
                            mergeRouterOperation(routerOperation, userRouterOperation);
                    }
                } else if (function.isSupplier()) {
                    for (RequestMethod requestMethod : supplierRequestMethods) {
                        RouterOperation routerOperation = buildRouterOperation(name, " supplier", requestMethod, routerOperationList);
                        ApiResponses apiResponses = buildResponses(openAPI, function, new String[] { springDocConfigProperties.getDefaultProducesMediaType() });
                        routerOperation.getOperationModel().responses(apiResponses);
                        if (StringUtils.isEmpty(prefix))
                            routerOperation.setPath(AntPathMatcher.DEFAULT_PATH_SEPARATOR + name);
                        else
                            routerOperation.setPath(prefix + AntPathMatcher.DEFAULT_PATH_SEPARATOR + name);
                        RouterOperation userRouterOperation = this.getRouterFunctionPaths(name, requestMethod);
                        if (userRouterOperation != null)
                            mergeRouterOperation(routerOperation, userRouterOperation);
                    }
                }
            }
        }
    });
    return routerOperationList;
}
Also used : RouterOperation(org.springdoc.core.fn.RouterOperation) FunctionInvocationWrapper(org.springframework.cloud.function.context.catalog.SimpleFunctionRegistry.FunctionInvocationWrapper) RequestMethod(org.springframework.web.bind.annotation.RequestMethod) Content(io.swagger.v3.oas.models.media.Content) ArrayList(java.util.ArrayList) ApiResponses(io.swagger.v3.oas.models.responses.ApiResponses) ApiResponse(io.swagger.v3.oas.models.responses.ApiResponse)

Example 3 with RouterOperation

use of org.springdoc.core.fn.RouterOperation in project springdoc-openapi by springdoc.

the class AbstractOpenApiResourceTest method calculatePathFromRouterOperation.

@Test
void calculatePathFromRouterOperation() {
    resource = new EmptyPathsOpenApiResource(GROUP_NAME, openAPIBuilderObjectFactory, requestBuilder, responseBuilder, operationParser, Optional.empty(), Optional.empty(), Optional.empty(), new SpringDocConfigProperties(), springDocProviders);
    final Parameter refParameter = new Parameter().$ref(PARAMETER_REFERENCE);
    final Parameter numberParameterInPath = new Parameter().name(PARAMETER_WITH_NUMBER_SCHEMA_NAME).in(ParameterIn.PATH.toString()).schema(new NumberSchema());
    final Parameter parameterWithoutSchema = new Parameter().name(PARAMETER_WITHOUT_SCHEMA_NAME);
    final Operation operation = new Operation();
    operation.setParameters(asList(refParameter, numberParameterInPath, parameterWithoutSchema));
    final RouterOperation routerOperation = new RouterOperation();
    routerOperation.setMethods(new RequestMethod[] { GET });
    routerOperation.setOperationModel(operation);
    routerOperation.setPath(PATH);
    resource.calculatePath(routerOperation, Locale.getDefault());
    final List<Parameter> parameters = resource.getOpenApi(Locale.getDefault()).getPaths().get(PATH).getGet().getParameters();
    assertThat(parameters.size(), is(3));
    assertThat(parameters, containsInAnyOrder(refParameter, numberParameterInPath, parameterWithoutSchema));
    assertThat(refParameter.getName(), nullValue());
    assertThat(refParameter.get$ref(), is(PARAMETER_REFERENCE));
    assertThat(refParameter.getSchema(), nullValue());
    assertThat(refParameter.getIn(), nullValue());
    assertThat(numberParameterInPath.getName(), is(PARAMETER_WITH_NUMBER_SCHEMA_NAME));
    assertThat(numberParameterInPath.get$ref(), nullValue());
    assertThat(numberParameterInPath.getSchema(), is(new NumberSchema()));
    assertThat(numberParameterInPath.getIn(), is(ParameterIn.PATH.toString()));
    assertThat(parameterWithoutSchema.getName(), is(PARAMETER_WITHOUT_SCHEMA_NAME));
    assertThat(parameterWithoutSchema.get$ref(), nullValue());
    assertThat(parameterWithoutSchema.getSchema(), is(new StringSchema()));
    assertThat(parameterWithoutSchema.getIn(), is(ParameterIn.QUERY.toString()));
}
Also used : RouterOperation(org.springdoc.core.fn.RouterOperation) SpringDocConfigProperties(org.springdoc.core.SpringDocConfigProperties) Parameter(io.swagger.v3.oas.models.parameters.Parameter) NumberSchema(io.swagger.v3.oas.models.media.NumberSchema) StringSchema(io.swagger.v3.oas.models.media.StringSchema) Operation(io.swagger.v3.oas.models.Operation) RouterOperation(org.springdoc.core.fn.RouterOperation) Test(org.junit.jupiter.api.Test)

Example 4 with RouterOperation

use of org.springdoc.core.fn.RouterOperation in project springdoc-openapi by springdoc.

the class AbstractOpenApiResource method getRouterFunctionPaths.

/**
 * Gets router function paths.
 *
 * @param beanName the bean name
 * @param routerFunctionVisitor the router function visitor
 * @param locale the locale
 */
protected void getRouterFunctionPaths(String beanName, AbstractRouterFunctionVisitor routerFunctionVisitor, Locale locale) {
    boolean withRouterOperation = routerFunctionVisitor.getRouterFunctionDatas().stream().anyMatch(routerFunctionData -> routerFunctionData.getAttributes().containsKey(OPERATION_ATTRIBUTE));
    if (withRouterOperation) {
        List<RouterOperation> operationList = routerFunctionVisitor.getRouterFunctionDatas().stream().map(RouterOperation::new).collect(Collectors.toList());
        calculatePath(operationList, locale);
    } else {
        List<org.springdoc.core.annotations.RouterOperation> routerOperationList = new ArrayList<>();
        ApplicationContext applicationContext = openAPIService.getContext();
        RouterOperations routerOperations = applicationContext.findAnnotationOnBean(beanName, RouterOperations.class);
        if (routerOperations == null) {
            org.springdoc.core.annotations.RouterOperation routerOperation = applicationContext.findAnnotationOnBean(beanName, org.springdoc.core.annotations.RouterOperation.class);
            if (routerOperation != null)
                routerOperationList.add(routerOperation);
        } else
            routerOperationList.addAll(Arrays.asList(routerOperations.value()));
        if (routerOperationList.size() == 1)
            calculatePath(routerOperationList.stream().map(routerOperation -> new RouterOperation(routerOperation, routerFunctionVisitor.getRouterFunctionDatas().get(0))).collect(Collectors.toList()), locale);
        else {
            List<RouterOperation> operationList = routerOperationList.stream().map(RouterOperation::new).collect(Collectors.toList());
            mergeRouters(routerFunctionVisitor.getRouterFunctionDatas(), operationList);
            calculatePath(operationList, locale);
        }
    }
}
Also used : RouterOperations(org.springdoc.core.annotations.RouterOperations) Arrays(java.util.Arrays) JsonView(com.fasterxml.jackson.annotation.JsonView) URLDecoder(java.net.URLDecoder) AopUtils(org.springframework.aop.support.AopUtils) Yaml(io.swagger.v3.core.util.Yaml) URISyntaxException(java.net.URISyntaxException) Parameter(io.swagger.v3.oas.models.parameters.Parameter) LoggerFactory(org.slf4j.LoggerFactory) Operation(io.swagger.v3.oas.models.Operation) DOT(org.springdoc.core.Constants.DOT) StringUtils(org.apache.commons.lang3.StringUtils) OpenApiLocaleCustomizer(org.springdoc.core.customizers.OpenApiLocaleCustomizer) HandlerMethod(org.springframework.web.method.HandlerMethod) JavadocProvider(org.springdoc.core.providers.JavadocProvider) OpenApiMethodFilter(org.springdoc.core.filters.OpenApiMethodFilter) SchemaPropertyDeprecatingConverter.isDeprecated(org.springdoc.core.converters.SchemaPropertyDeprecatingConverter.isDeprecated) Locale(java.util.Locale) Duration(java.time.Duration) Map(java.util.Map) OperationService(org.springdoc.core.OperationService) CloudFunctionProvider(org.springdoc.core.providers.CloudFunctionProvider) URI(java.net.URI) RouterOperation(org.springdoc.core.fn.RouterOperation) AntPathMatcher(org.springframework.util.AntPathMatcher) TypeReference(com.fasterxml.jackson.core.type.TypeReference) ACTUATOR_DEFAULT_GROUP(org.springdoc.core.Constants.ACTUATOR_DEFAULT_GROUP) Method(java.lang.reflect.Method) SortedOpenAPIMixin(org.springdoc.api.mixins.SortedOpenAPIMixin) MethodAttributes(org.springdoc.core.MethodAttributes) Hidden(io.swagger.v3.oas.annotations.Hidden) Collection(java.util.Collection) AnnotationUtils(org.springframework.core.annotation.AnnotationUtils) Set(java.util.Set) RequestMethod(org.springframework.web.bind.annotation.RequestMethod) Paths(io.swagger.v3.oas.models.Paths) Instant(java.time.Instant) Collectors(java.util.stream.Collectors) StandardCharsets(java.nio.charset.StandardCharsets) Executors(java.util.concurrent.Executors) DEFAULT_PATH_SEPARATOR(org.springframework.util.AntPathMatcher.DEFAULT_PATH_SEPARATOR) Objects(java.util.Objects) List(java.util.List) HttpMethod(io.swagger.v3.oas.models.PathItem.HttpMethod) Server(io.swagger.v3.oas.models.servers.Server) StringSchema(io.swagger.v3.oas.models.media.StringSchema) Environment(org.springframework.core.env.Environment) CollectionUtils(org.springframework.util.CollectionUtils) Optional(java.util.Optional) UnsupportedEncodingException(java.io.UnsupportedEncodingException) Feature(com.fasterxml.jackson.dataformat.yaml.YAMLGenerator.Feature) OperationCustomizer(org.springdoc.core.customizers.OperationCustomizer) AnnotatedElementUtils(org.springframework.core.annotation.AnnotatedElementUtils) ActuatorProvider(org.springdoc.core.providers.ActuatorProvider) Json(io.swagger.v3.core.util.Json) GenericResponseService(org.springdoc.core.GenericResponseService) AbstractRouterFunctionVisitor(org.springdoc.core.fn.AbstractRouterFunctionVisitor) OPERATION_ATTRIBUTE(org.springdoc.core.Constants.OPERATION_ATTRIBUTE) RequestMapping(org.springframework.web.bind.annotation.RequestMapping) ArrayUtils(org.apache.commons.lang3.ArrayUtils) SpecFilter(io.swagger.v3.core.filter.SpecFilter) ParameterIn(io.swagger.v3.oas.annotations.enums.ParameterIn) ArrayList(java.util.ArrayList) LINKS_SCHEMA_CUSTOMISER(org.springdoc.core.Constants.LINKS_SCHEMA_CUSTOMISER) HashSet(java.util.HashSet) LinkedHashMap(java.util.LinkedHashMap) RequestBody(org.springframework.web.bind.annotation.RequestBody) MapperFeature(com.fasterxml.jackson.databind.MapperFeature) OpenAPI(io.swagger.v3.oas.models.OpenAPI) SortedSchemaMixin(org.springdoc.api.mixins.SortedSchemaMixin) YAMLFactory(com.fasterxml.jackson.dataformat.yaml.YAMLFactory) OpenAPIService(org.springdoc.core.OpenAPIService) AbstractRequestService(org.springdoc.core.AbstractRequestService) Schema(io.swagger.v3.oas.models.media.Schema) SpringDocProviders(org.springdoc.core.SpringDocProviders) OpenApiCustomiser(org.springdoc.core.customizers.OpenApiCustomiser) GenericParameterService(org.springdoc.core.GenericParameterService) ApiResponses(io.swagger.v3.oas.models.responses.ApiResponses) SpringDocConfigProperties(org.springdoc.core.SpringDocConfigProperties) Logger(org.slf4j.Logger) RouterFunctionData(org.springdoc.core.fn.RouterFunctionData) ObjectMapper(com.fasterxml.jackson.databind.ObjectMapper) PathItem(io.swagger.v3.oas.models.PathItem) JsonProcessingException(com.fasterxml.jackson.core.JsonProcessingException) Callback(io.swagger.v3.oas.annotations.callbacks.Callback) ResponseBody(org.springframework.web.bind.annotation.ResponseBody) ApplicationContext(org.springframework.context.ApplicationContext) GroupConfig(org.springdoc.core.SpringDocConfigProperties.GroupConfig) ReflectionUtils(io.swagger.v3.core.util.ReflectionUtils) ObjectFactory(org.springframework.beans.factory.ObjectFactory) Components(io.swagger.v3.oas.models.Components) SerializationFeature(com.fasterxml.jackson.databind.SerializationFeature) SPRING_MVC_SERVLET_PATH(org.springdoc.core.Constants.SPRING_MVC_SERVLET_PATH) Collections(java.util.Collections) RouterOperations(org.springdoc.core.annotations.RouterOperations) ArrayList(java.util.ArrayList) RouterOperation(org.springdoc.core.fn.RouterOperation) ApplicationContext(org.springframework.context.ApplicationContext)

Example 5 with RouterOperation

use of org.springdoc.core.fn.RouterOperation in project springdoc-openapi by springdoc.

the class AbstractOpenApiResource method calculatePath.

/**
 * Calculate path.
 *
 * @param handlerMethod the handler method
 * @param routerOperation the router operation
 * @param locale the locale
 */
protected void calculatePath(HandlerMethod handlerMethod, RouterOperation routerOperation, Locale locale) {
    String operationPath = routerOperation.getPath();
    Set<RequestMethod> requestMethods = new HashSet<>(Arrays.asList(routerOperation.getMethods()));
    io.swagger.v3.oas.annotations.Operation apiOperation = routerOperation.getOperation();
    String[] methodConsumes = routerOperation.getConsumes();
    String[] methodProduces = routerOperation.getProduces();
    String[] headers = routerOperation.getHeaders();
    Map<String, String> queryParams = routerOperation.getQueryParams();
    OpenAPI openAPI = openAPIService.getCalculatedOpenAPI();
    Components components = openAPI.getComponents();
    Paths paths = openAPI.getPaths();
    Map<HttpMethod, Operation> operationMap = null;
    if (paths.containsKey(operationPath)) {
        PathItem pathItem = paths.get(operationPath);
        operationMap = pathItem.readOperationsMap();
    }
    JavadocProvider javadocProvider = operationParser.getJavadocProvider();
    for (RequestMethod requestMethod : requestMethods) {
        Operation existingOperation = getExistingOperation(operationMap, requestMethod);
        Method method = handlerMethod.getMethod();
        // skip hidden operations
        if (operationParser.isHidden(method))
            continue;
        RequestMapping reqMappingClass = AnnotatedElementUtils.findMergedAnnotation(handlerMethod.getBeanType(), RequestMapping.class);
        MethodAttributes methodAttributes = new MethodAttributes(springDocConfigProperties.getDefaultConsumesMediaType(), springDocConfigProperties.getDefaultProducesMediaType(), methodConsumes, methodProduces, headers, locale);
        methodAttributes.setMethodOverloaded(existingOperation != null);
        // Use the javadoc return if present
        if (javadocProvider != null) {
            methodAttributes.setJavadocReturn(javadocProvider.getMethodJavadocReturn(handlerMethod.getMethod()));
        }
        if (reqMappingClass != null) {
            methodAttributes.setClassConsumes(reqMappingClass.consumes());
            methodAttributes.setClassProduces(reqMappingClass.produces());
        }
        methodAttributes.calculateHeadersForClass(method.getDeclaringClass());
        methodAttributes.calculateConsumesProduces(method);
        Operation operation = (existingOperation != null) ? existingOperation : new Operation();
        if (isDeprecated(method))
            operation.setDeprecated(true);
        // Add documentation from operation annotation
        if (apiOperation == null || StringUtils.isBlank(apiOperation.operationId()))
            apiOperation = AnnotatedElementUtils.findMergedAnnotation(method, io.swagger.v3.oas.annotations.Operation.class);
        calculateJsonView(apiOperation, methodAttributes, method);
        if (apiOperation != null)
            openAPI = operationParser.parse(apiOperation, operation, openAPI, methodAttributes);
        fillParametersList(operation, queryParams, methodAttributes);
        // compute tags
        operation = openAPIService.buildTags(handlerMethod, operation, openAPI, locale);
        io.swagger.v3.oas.annotations.parameters.RequestBody requestBodyDoc = AnnotatedElementUtils.findMergedAnnotation(method, io.swagger.v3.oas.annotations.parameters.RequestBody.class);
        // RequestBody in Operation
        requestBuilder.getRequestBodyBuilder().buildRequestBodyFromDoc(requestBodyDoc, methodAttributes, components, methodAttributes.getJsonViewAnnotationForRequestBody()).ifPresent(operation::setRequestBody);
        // requests
        operation = requestBuilder.build(handlerMethod, requestMethod, operation, methodAttributes, openAPI);
        // responses
        ApiResponses apiResponses = responseBuilder.build(components, handlerMethod, operation, methodAttributes);
        operation.setResponses(apiResponses);
        // get javadoc method description
        if (javadocProvider != null) {
            String description = javadocProvider.getMethodJavadocDescription(handlerMethod.getMethod());
            if (!StringUtils.isEmpty(description) && StringUtils.isEmpty(operation.getDescription()))
                operation.setDescription(description);
        }
        Set<io.swagger.v3.oas.annotations.callbacks.Callback> apiCallbacks = AnnotatedElementUtils.findMergedRepeatableAnnotations(method, io.swagger.v3.oas.annotations.callbacks.Callback.class);
        // callbacks
        buildCallbacks(openAPI, methodAttributes, operation, apiCallbacks);
        // allow for customisation
        operation = customiseOperation(operation, handlerMethod);
        PathItem pathItemObject = buildPathItem(requestMethod, operation, operationPath, paths);
        paths.addPathItem(operationPath, pathItemObject);
    }
}
Also used : RequestMethod(org.springframework.web.bind.annotation.RequestMethod) JavadocProvider(org.springdoc.core.providers.JavadocProvider) Operation(io.swagger.v3.oas.models.Operation) RouterOperation(org.springdoc.core.fn.RouterOperation) RequestMapping(org.springframework.web.bind.annotation.RequestMapping) Components(io.swagger.v3.oas.models.Components) PathItem(io.swagger.v3.oas.models.PathItem) Paths(io.swagger.v3.oas.models.Paths) ApiResponses(io.swagger.v3.oas.models.responses.ApiResponses) HashSet(java.util.HashSet) HandlerMethod(org.springframework.web.method.HandlerMethod) Method(java.lang.reflect.Method) RequestMethod(org.springframework.web.bind.annotation.RequestMethod) HttpMethod(io.swagger.v3.oas.models.PathItem.HttpMethod) Callback(io.swagger.v3.oas.annotations.callbacks.Callback) OpenAPI(io.swagger.v3.oas.models.OpenAPI) HttpMethod(io.swagger.v3.oas.models.PathItem.HttpMethod) MethodAttributes(org.springdoc.core.MethodAttributes)

Aggregations

RouterOperation (org.springdoc.core.fn.RouterOperation)15 Operation (io.swagger.v3.oas.models.Operation)10 OpenAPI (io.swagger.v3.oas.models.OpenAPI)9 ArrayList (java.util.ArrayList)8 RequestMethod (org.springframework.web.bind.annotation.RequestMethod)8 HandlerMethod (org.springframework.web.method.HandlerMethod)8 ApiResponses (io.swagger.v3.oas.models.responses.ApiResponses)7 List (java.util.List)7 SpringDocConfigProperties (org.springdoc.core.SpringDocConfigProperties)7 ObjectMapper (com.fasterxml.jackson.databind.ObjectMapper)6 Parameter (io.swagger.v3.oas.models.parameters.Parameter)6 HashSet (java.util.HashSet)6 Locale (java.util.Locale)6 Map (java.util.Map)6 MethodAttributes (org.springdoc.core.MethodAttributes)6 ApplicationContext (org.springframework.context.ApplicationContext)6 JsonProcessingException (com.fasterxml.jackson.core.JsonProcessingException)5 Schema (io.swagger.v3.oas.models.media.Schema)5 Optional (java.util.Optional)5 Set (java.util.Set)5