feat: 初始化

This commit is contained in:
2024-04-09 11:34:46 +08:00
commit 39f3acc15f
3209 changed files with 253442 additions and 0 deletions
@@ -0,0 +1,65 @@
package cc.mrbird.febs.common.doc.gateway.configure;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
import org.springframework.boot.context.properties.EnableConfigurationProperties;
import org.springframework.cloud.gateway.config.GatewayProperties;
import org.springframework.cloud.gateway.route.RouteLocator;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Primary;
import cc.mrbird.febs.common.doc.gateway.filter.FebsDocGatewayHeaderFilter;
import cc.mrbird.febs.common.doc.gateway.handler.FebsDocGatewayHandler;
import cc.mrbird.febs.common.doc.gateway.properties.FebsDocGatewayProperties;
import springfox.documentation.swagger.web.SecurityConfiguration;
import springfox.documentation.swagger.web.SwaggerResourcesProvider;
import springfox.documentation.swagger.web.UiConfiguration;
/**
* @author MrBird
*/
@Configuration
@EnableConfigurationProperties(FebsDocGatewayProperties.class)
@ConditionalOnProperty(value = "febs.doc.gateway.enable", havingValue = "true", matchIfMissing = true)
public class FebsDocGatewayAutoConfigure {
private final FebsDocGatewayProperties febsDocGatewayProperties;
private SecurityConfiguration securityConfiguration;
private UiConfiguration uiConfiguration;
public FebsDocGatewayAutoConfigure(FebsDocGatewayProperties febsDocGatewayProperties) {
this.febsDocGatewayProperties = febsDocGatewayProperties;
}
@Autowired(required = false)
public void setSecurityConfiguration(SecurityConfiguration securityConfiguration) {
this.securityConfiguration = securityConfiguration;
}
@Autowired(required = false)
public void setUiConfiguration(UiConfiguration uiConfiguration) {
this.uiConfiguration = uiConfiguration;
}
@Bean
@Primary
public FebsDocGatewayResourceConfigure febsDocGatewayResourceConfigure(RouteLocator routeLocator, GatewayProperties gatewayProperties) {
return new FebsDocGatewayResourceConfigure(routeLocator, gatewayProperties);
}
@Bean
public FebsDocGatewayHeaderFilter febsDocGatewayHeaderFilter() {
return new FebsDocGatewayHeaderFilter();
}
@Bean
public FebsDocGatewayHandler febsDocGatewayHandler(SwaggerResourcesProvider swaggerResources) {
FebsDocGatewayHandler febsDocGatewayHandler = new FebsDocGatewayHandler();
febsDocGatewayHandler.setSecurityConfiguration(securityConfiguration);
febsDocGatewayHandler.setUiConfiguration(uiConfiguration);
febsDocGatewayHandler.setSwaggerResources(swaggerResources);
febsDocGatewayHandler.setProperties(febsDocGatewayProperties);
return febsDocGatewayHandler;
}
}
@@ -0,0 +1,50 @@
package cc.mrbird.febs.common.doc.gateway.configure;
import org.springframework.cloud.gateway.config.GatewayProperties;
import org.springframework.cloud.gateway.route.RouteLocator;
import org.springframework.cloud.gateway.support.NameUtils;
import java.util.ArrayList;
import java.util.List;
import springfox.documentation.swagger.web.SwaggerResource;
import springfox.documentation.swagger.web.SwaggerResourcesProvider;
/**
* @author MrBird
*/
public class FebsDocGatewayResourceConfigure implements SwaggerResourcesProvider {
private final RouteLocator routeLocator;
private final GatewayProperties gatewayProperties;
public FebsDocGatewayResourceConfigure(RouteLocator routeLocator, GatewayProperties gatewayProperties) {
this.routeLocator = routeLocator;
this.gatewayProperties = gatewayProperties;
}
@Override
public List<SwaggerResource> get() {
List<SwaggerResource> resources = new ArrayList<>();
List<String> routes = new ArrayList<>();
routeLocator.getRoutes().subscribe(route -> routes.add(route.getId()));
gatewayProperties.getRoutes().stream().filter(routeDefinition -> routes.contains(routeDefinition.getId())).forEach(route -> route.getPredicates().stream()
.filter(predicateDefinition -> ("Path").equalsIgnoreCase(predicateDefinition.getName()))
.forEach(predicateDefinition -> resources.add(swaggerResource(route.getId(),
predicateDefinition.getArgs().get(NameUtils.GENERATED_NAME_PREFIX + "0")
.replace("**", "v2/api-docs")))));
return resources;
}
private SwaggerResource swaggerResource(String name, String location) {
SwaggerResource swaggerResource = new SwaggerResource();
swaggerResource.setName(name);
swaggerResource.setLocation(location);
swaggerResource.setSwaggerVersion("2.0");
return swaggerResource;
}
}
@@ -0,0 +1,32 @@
package cc.mrbird.febs.common.doc.gateway.filter;
import org.springframework.cloud.gateway.filter.GatewayFilter;
import org.springframework.cloud.gateway.filter.factory.AbstractGatewayFilterFactory;
import org.springframework.http.server.reactive.ServerHttpRequest;
import org.springframework.util.StringUtils;
import org.springframework.web.server.ServerWebExchange;
/**
* @author MrBird
*/
@SuppressWarnings("all")
public class FebsDocGatewayHeaderFilter extends AbstractGatewayFilterFactory {
private static final String HEADER_NAME = "X-Forwarded-Prefix";
private static final String URI = "/v2/api-docs";
@Override
public GatewayFilter apply(Object config) {
return (exchange, chain) -> {
ServerHttpRequest request = exchange.getRequest();
String path = request.getURI().getPath();
if (!StringUtils.endsWithIgnoreCase(path, URI)) {
return chain.filter(exchange);
}
String basePath = path.substring(0, path.lastIndexOf(URI));
ServerHttpRequest newRequest = request.mutate().header(HEADER_NAME, basePath).build();
ServerWebExchange newExchange = exchange.mutate().request(newRequest).build();
return chain.filter(newExchange);
};
}
}
@@ -0,0 +1,76 @@
package cc.mrbird.febs.common.doc.gateway.handler;
import cc.mrbird.febs.common.doc.gateway.properties.FebsDocGatewayProperties;
import org.apache.commons.lang3.StringUtils;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;
import reactor.core.publisher.Mono;
import springfox.documentation.swagger.web.*;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.Optional;
/**
* @author MrBird
*/
@RestController
public class FebsDocGatewayHandler {
private SecurityConfiguration securityConfiguration;
private UiConfiguration uiConfiguration;
private SwaggerResourcesProvider swaggerResources;
private FebsDocGatewayProperties properties;
public void setSecurityConfiguration(SecurityConfiguration securityConfiguration) {
this.securityConfiguration = securityConfiguration;
}
public void setUiConfiguration(UiConfiguration uiConfiguration) {
this.uiConfiguration = uiConfiguration;
}
public void setSwaggerResources(SwaggerResourcesProvider swaggerResources) {
this.swaggerResources = swaggerResources;
}
public void setProperties(FebsDocGatewayProperties properties) {
this.properties = properties;
}
@GetMapping("/swagger-resources/configuration/security")
public Mono<ResponseEntity<SecurityConfiguration>> securityConfiguration() {
return Mono.just(new ResponseEntity<>(
Optional.ofNullable(securityConfiguration).orElse(SecurityConfigurationBuilder.builder().build()), HttpStatus.OK));
}
@GetMapping("/swagger-resources/configuration/ui")
public Mono<ResponseEntity<UiConfiguration>> uiConfiguration() {
return Mono.just(new ResponseEntity<>(
Optional.ofNullable(uiConfiguration).orElse(UiConfigurationBuilder.builder().build()), HttpStatus.OK));
}
@GetMapping("/swagger-resources")
public Mono<ResponseEntity<List<SwaggerResource>>> swaggerResources() {
List<SwaggerResource> swaggerResources = this.swaggerResources.get();
List<SwaggerResource> filterList = new ArrayList<>();
String resources = properties.getResources();
String[] resourcesArray = StringUtils.splitByWholeSeparatorPreserveAllTokens(resources, ",");
if (resourcesArray != null && resources.length() > 0) {
boolean include = false;
for (SwaggerResource resource : swaggerResources) {
if (Arrays.stream(resourcesArray).anyMatch(r -> StringUtils.equalsIgnoreCase(r, resource.getName()))) {
include = true;
}
if (include) {
filterList.add(resource);
}
}
return Mono.just((new ResponseEntity<>(filterList, HttpStatus.OK)));
}
return Mono.just((new ResponseEntity<>(swaggerResources, HttpStatus.OK)));
}
}
@@ -0,0 +1,45 @@
package cc.mrbird.febs.common.doc.gateway.properties;
import org.springframework.boot.context.properties.ConfigurationProperties;
/**
* @author MrBird
*/
@ConfigurationProperties(prefix = "febs.doc.gateway")
public class FebsDocGatewayProperties {
/**
* 是否开启网关文档聚合功能
*/
private Boolean enable;
/**
* 需要暴露doc的服务列表,多个值时用逗号分隔
* 如 FEBS-Auth,FEBS-Server-System
*/
private String resources;
public String getResources() {
return resources;
}
public void setResources(String resources) {
this.resources = resources;
}
public Boolean getEnable() {
return enable;
}
public void setEnable(Boolean enable) {
this.enable = enable;
}
@Override
public String toString() {
return "FebsDocGatewayProperties{" +
"enable=" + enable +
", resources='" + resources + '\'' +
'}';
}
}
@@ -0,0 +1,3 @@
# Auto Configure
org.springframework.boot.autoconfigure.EnableAutoConfiguration=\
cc.mrbird.febs.common.doc.gateway.configure.FebsDocGatewayAutoConfigure