Skip to content

Commit

Permalink
[Improvement] add springdoc-openapi-ui (apache#12379)
Browse files Browse the repository at this point in the history
Co-authored-by: fuchanghai <‘2875334588@qq.com’>
Co-authored-by: Wenjun Ruan <wenjun@apache.org>
  • Loading branch information
3 people authored and Chris-Arith committed Oct 26, 2022
1 parent 2e490f0 commit cd79098
Show file tree
Hide file tree
Showing 79 changed files with 1,890 additions and 3,177 deletions.
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

0 comments on commit cd79098

Please sign in to comment.