Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[Improvement] add springdoc-openapi-ui #12379

Merged
merged 14 commits into from
Oct 23, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
9 changes: 4 additions & 5 deletions dolphinscheduler-api/pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -134,11 +134,6 @@
<artifactId>spring-context</artifactId>
</dependency>

<dependency>
<groupId>io.springfox</groupId>
<artifactId>springfox-boot-starter</artifactId>
</dependency>

<dependency>
<groupId>org.hibernate.validator</groupId>
<artifactId>hibernate-validator</artifactId>
Expand Down Expand Up @@ -195,6 +190,10 @@
<scope>test</scope>
</dependency>

<dependency>
<groupId>org.springdoc</groupId>
<artifactId>springdoc-openapi-ui</artifactId>
</dependency>
</dependencies>
<build>
<testResources>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -103,7 +103,7 @@ public void addInterceptors(InterceptorRegistry registry) {
registry.addInterceptor(loginInterceptor())
.addPathPatterns(LOGIN_INTERCEPTOR_PATH_PATTERN)
.excludePathPatterns(LOGIN_PATH_PATTERN, REGISTER_PATH_PATTERN,
"/swagger-resources/**", "/webjars/**", "/v3/api-docs/**", "/api-docs/**",
"/swagger-resources/**", "/webjars/**", "/v3/api-docs/**", "/api-docs/**", "/swagger-ui.html",
"/doc.html", "/swagger-ui/**", "*.html", "/ui/**", "/error");
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,107 +16,46 @@
*/
package org.apache.dolphinscheduler.api.configuration;

import springfox.documentation.builders.ApiInfoBuilder;
import springfox.documentation.builders.PathSelectors;
import springfox.documentation.builders.RequestHandlerSelectors;
import springfox.documentation.service.ApiInfo;
import springfox.documentation.spi.DocumentationType;
import springfox.documentation.spring.web.plugins.Docket;
import springfox.documentation.spring.web.plugins.WebFluxRequestHandlerProvider;
import springfox.documentation.spring.web.plugins.WebMvcRequestHandlerProvider;

import java.lang.reflect.Field;
import java.util.List;
import java.util.stream.Collectors;

import org.springframework.beans.BeansException;
import org.springframework.beans.factory.config.BeanPostProcessor;
import org.springdoc.core.GroupedOpenApi;
import org.springframework.boot.autoconfigure.condition.ConditionalOnWebApplication;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.PropertySource;
import org.springframework.util.ReflectionUtils;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;
import org.springframework.web.servlet.mvc.method.RequestMappingInfoHandlerMapping;

import io.swagger.v3.oas.models.OpenAPI;
import io.swagger.v3.oas.models.info.Info;

/**
*
* swager2 config class
*
*/
@Configuration
@ConditionalOnWebApplication
@PropertySource("classpath:swagger.properties")
public class OpenAPIConfiguration implements WebMvcConfigurer {

@Bean
public Docket createV1RestApi() {
return new Docket(DocumentationType.OAS_30)
.groupName("v1(current)")
.apiInfo(apiV1Info())
.select()
.apis(RequestHandlerSelectors.basePackage("org.apache.dolphinscheduler.api.controller"))
.paths(PathSelectors.any().and(PathSelectors.ant("/v2/**").negate()))
.build();
}

private ApiInfo apiV1Info() {
return new ApiInfoBuilder()
.title("Dolphin Scheduler Api Docs")
.description("Dolphin Scheduler Api Docs")
.version("V1")
.build();
public OpenAPI apiV1Info1() {
return new OpenAPI()
.info(new Info()
.title("Dolphin Scheduler Api Docs")
.description("Dolphin Scheduler Api Docs")
.version("V1"));
}

@Bean
public Docket createV2RestApi() {
return new Docket(DocumentationType.OAS_30)
.groupName("v2")
.apiInfo(apiV2Info())
.select()
.apis(RequestHandlerSelectors.basePackage("org.apache.dolphinscheduler.api.controller"))
.paths(PathSelectors.any().and(PathSelectors.ant("/v2/**")))
.build();
}

private ApiInfo apiV2Info() {
return new ApiInfoBuilder()
.title("Dolphin Scheduler Api Docs")
.description("Dolphin Scheduler Api Docs")
.version("V2")
public GroupedOpenApi publicApi1() {
return GroupedOpenApi.builder()
.group("v1")
.pathsToExclude("/v2/**")
.build();
}

@Bean
public static BeanPostProcessor springfoxHandlerProviderBeanPostProcessor() {
return new BeanPostProcessor() {

@Override
public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {
if (bean instanceof WebMvcRequestHandlerProvider || bean instanceof WebFluxRequestHandlerProvider) {
customizeSpringfoxHandlerMappings(getHandlerMappings(bean));
}
return bean;
}

private <T extends RequestMappingInfoHandlerMapping> void customizeSpringfoxHandlerMappings(List<T> mappings) {
List<T> copy = mappings.stream()
.filter(mapping -> mapping.getPatternParser() == null)
.collect(Collectors.toList());
mappings.clear();
mappings.addAll(copy);
}

@SuppressWarnings("unchecked")
private List<RequestMappingInfoHandlerMapping> getHandlerMappings(Object bean) {
try {
Field field = ReflectionUtils.findField(bean.getClass(), "handlerMappings");
field.setAccessible(true);
return (List<RequestMappingInfoHandlerMapping>) field.get(bean);
} catch (IllegalArgumentException | IllegalAccessException e) {
throw new IllegalStateException(e);
}
}
};
public GroupedOpenApi publicApi2() {
return GroupedOpenApi.builder()
.group("v2")
.pathsToMatch("/v2/**")
.build();
}
}

This file was deleted.

Original file line number Diff line number Diff line change
Expand Up @@ -32,8 +32,6 @@
import org.apache.dolphinscheduler.dao.entity.User;
import org.apache.dolphinscheduler.plugin.task.api.utils.ParameterUtils;

import springfox.documentation.annotations.ApiIgnore;

import java.util.Map;

import org.springframework.beans.factory.annotation.Autowired;
Expand All @@ -49,15 +47,16 @@
import org.springframework.web.bind.annotation.ResponseStatus;
import org.springframework.web.bind.annotation.RestController;

import io.swagger.annotations.Api;
import io.swagger.annotations.ApiImplicitParam;
import io.swagger.annotations.ApiImplicitParams;
import io.swagger.annotations.ApiOperation;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.Parameter;
import io.swagger.v3.oas.annotations.Parameters;
import io.swagger.v3.oas.annotations.media.Schema;
import io.swagger.v3.oas.annotations.tags.Tag;

/**
* access token controller
*/
@Api(tags = "ACCESS_TOKEN_TAG")
@Tag(name = "ACCESS_TOKEN_TAG")
@RestController
@RequestMapping("/access-tokens")
public class AccessTokenController extends BaseController {
Expand All @@ -74,17 +73,17 @@ public class AccessTokenController extends BaseController {
* @param token token string (if it is absent, it will be automatically generated)
* @return create result state code
*/
@ApiOperation(value = "createToken", notes = "CREATE_TOKEN_NOTES")
@ApiImplicitParams({
@ApiImplicitParam(name = "userId", value = "USER_ID", required = true, dataTypeClass = int.class),
@ApiImplicitParam(name = "expireTime", value = "EXPIRE_TIME", required = true, dataTypeClass = String.class, example = "2021-12-31 00:00:00"),
@ApiImplicitParam(name = "token", value = "TOKEN", required = false, dataTypeClass = String.class, example = "xxxx")
@Operation(summary = "createToken", description = "CREATE_TOKEN_NOTES")
@Parameters({
@Parameter(name = "userId", description = "USER_ID", schema = @Schema(implementation = int.class), required = true),
@Parameter(name = "expireTime", description = "EXPIRE_TIME", schema = @Schema(implementation = String.class), required = true, example = "2021-12-31 00:00:00"),
@Parameter(name = "token", description = "TOKEN", required = false, schema = @Schema(implementation = String.class), example = "xxxx")
})
@PostMapping()
@ResponseStatus(HttpStatus.CREATED)
@ApiException(CREATE_ACCESS_TOKEN_ERROR)
@AccessLogAnnotation(ignoreRequestArgs = "loginUser")
public Result createToken(@ApiIgnore @RequestAttribute(value = Constants.SESSION_USER) User loginUser,
public Result createToken(@Parameter(hidden = true) @RequestAttribute(value = Constants.SESSION_USER) User loginUser,
@RequestParam(value = "userId") int userId,
@RequestParam(value = "expireTime") String expireTime,
@RequestParam(value = "token", required = false) String token) {
Expand All @@ -100,7 +99,7 @@ public Result createToken(@ApiIgnore @RequestAttribute(value = Constants.SESSION
* @param expireTime expire time
* @return token string
*/
@ApiIgnore
@Parameter(hidden = true)
@PostMapping(value = "/generate")
@ResponseStatus(HttpStatus.CREATED)
@ApiException(GENERATE_TOKEN_ERROR)
Expand All @@ -121,17 +120,17 @@ public Result generateToken(@RequestAttribute(value = Constants.SESSION_USER) Us
* @param pageSize page size
* @return token list of page number and page size
*/
@ApiOperation(value = "queryAccessTokenList", notes = "QUERY_ACCESS_TOKEN_LIST_NOTES")
@ApiImplicitParams({
@ApiImplicitParam(name = "searchVal", value = "SEARCH_VAL", dataTypeClass = String.class),
@ApiImplicitParam(name = "pageNo", value = "PAGE_NO", required = true, dataTypeClass = int.class, example = "1"),
@ApiImplicitParam(name = "pageSize", value = "PAGE_SIZE", required = true, dataTypeClass = int.class, example = "20")
@Operation(summary = "queryAccessTokenList", description = "QUERY_ACCESS_TOKEN_LIST_NOTES")
@Parameters({
@Parameter(name = "searchVal", description = "SEARCH_VAL", schema = @Schema(implementation = String.class)),
@Parameter(name = "pageNo", description = "PAGE_NO", required = true, schema = @Schema(implementation = int.class), example = "1"),
@Parameter(name = "pageSize", description = "PAGE_SIZE", required = true, schema = @Schema(implementation = int.class), example = "20")
})
@GetMapping()
@ResponseStatus(HttpStatus.OK)
@ApiException(QUERY_ACCESSTOKEN_LIST_PAGING_ERROR)
@AccessLogAnnotation(ignoreRequestArgs = "loginUser")
public Result queryAccessTokenList(@ApiIgnore @RequestAttribute(value = Constants.SESSION_USER) User loginUser,
public Result queryAccessTokenList(@Parameter(hidden = true) @RequestAttribute(value = Constants.SESSION_USER) User loginUser,
@RequestParam("pageNo") Integer pageNo,
@RequestParam(value = "searchVal", required = false) String searchVal,
@RequestParam("pageSize") Integer pageSize) {
Expand All @@ -152,15 +151,15 @@ public Result queryAccessTokenList(@ApiIgnore @RequestAttribute(value = Constant
* @param userId user id
* @return token list for specified user
*/
@ApiOperation(value = "queryAccessTokenByUser", notes = "QUERY_ACCESS_TOKEN_BY_USER_NOTES")
@ApiImplicitParams({
@ApiImplicitParam(name = "userId", value = "USER_ID", dataTypeClass = int.class)
@Operation(summary = "queryAccessTokenByUser", description = "QUERY_ACCESS_TOKEN_BY_USER_NOTES")
@Parameters({
@Parameter(name = "userId", description = "USER_ID", schema = @Schema(implementation = int.class))
})
@GetMapping(value = "/user/{userId}")
@ResponseStatus(HttpStatus.OK)
@ApiException(QUERY_ACCESSTOKEN_BY_USER_ERROR)
@AccessLogAnnotation(ignoreRequestArgs = "loginUser")
public Result queryAccessTokenByUser(@ApiIgnore @RequestAttribute(value = Constants.SESSION_USER) User loginUser,
public Result queryAccessTokenByUser(@Parameter(hidden = true) @RequestAttribute(value = Constants.SESSION_USER) User loginUser,
@PathVariable("userId") Integer userId) {
Map<String, Object> result = this.accessTokenService.queryAccessTokenByUser(loginUser, userId);
return this.returnDataList(result);
Expand All @@ -173,12 +172,12 @@ public Result queryAccessTokenByUser(@ApiIgnore @RequestAttribute(value = Consta
* @param id token id
* @return delete result code
*/
@ApiIgnore
@Parameter(hidden = true)
@DeleteMapping(value = "/{id}")
@ResponseStatus(HttpStatus.OK)
@ApiException(DELETE_ACCESS_TOKEN_ERROR)
@AccessLogAnnotation(ignoreRequestArgs = "loginUser")
public Result delAccessTokenById(@ApiIgnore @RequestAttribute(value = Constants.SESSION_USER) User loginUser,
public Result delAccessTokenById(@Parameter(hidden = true) @RequestAttribute(value = Constants.SESSION_USER) User loginUser,
@PathVariable(value = "id") int id) {
Map<String, Object> result = accessTokenService.delAccessTokenById(loginUser, id);
return returnDataList(result);
Expand All @@ -194,18 +193,18 @@ public Result delAccessTokenById(@ApiIgnore @RequestAttribute(value = Constants.
* @param token token string (if it is absent, it will be automatically generated)
* @return updated access token entity
*/
@ApiOperation(value = "updateToken", notes = "UPDATE_TOKEN_NOTES")
@ApiImplicitParams({
@ApiImplicitParam(name = "id", value = "TOKEN_ID", required = true, dataTypeClass = int.class),
@ApiImplicitParam(name = "userId", value = "USER_ID", required = true, dataTypeClass = int.class),
@ApiImplicitParam(name = "expireTime", value = "EXPIRE_TIME", required = true, dataTypeClass = String.class, example = "2021-12-31 00:00:00"),
@ApiImplicitParam(name = "token", value = "TOKEN", required = false, dataTypeClass = String.class, example = "xxxx")
@Operation(summary = "updateToken", description = "UPDATE_TOKEN_NOTES")
@Parameters({
@Parameter(name = "id", description = "TOKEN_ID", required = true, schema = @Schema(implementation = int.class)),
@Parameter(name = "userId", description = "USER_ID", required = true, schema = @Schema(implementation = int.class)),
@Parameter(name = "expireTime", description = "EXPIRE_TIME", required = true, schema = @Schema(implementation = String.class), example = "2021-12-31 00:00:00"),
@Parameter(name = "token", description = "TOKEN", required = false, schema = @Schema(implementation = String.class), example = "xxxx")
})
@PutMapping(value = "/{id}")
@ResponseStatus(HttpStatus.OK)
@ApiException(UPDATE_ACCESS_TOKEN_ERROR)
@AccessLogAnnotation(ignoreRequestArgs = "loginUser")
public Result updateToken(@ApiIgnore @RequestAttribute(value = Constants.SESSION_USER) User loginUser,
public Result updateToken(@Parameter(hidden = true) @RequestAttribute(value = Constants.SESSION_USER) User loginUser,
@PathVariable(value = "id") int id,
@RequestParam(value = "userId") int userId,
@RequestParam(value = "expireTime") String expireTime,
Expand Down
Loading