From ce54ddf73bdf7191379d9f84e8a98d441b9dbbbe Mon Sep 17 00:00:00 2001 From: lbw Date: Mon, 4 Sep 2023 09:01:15 +0800 Subject: [PATCH] =?UTF-8?q?:recycle:=20Refactoring=20code.=20swagger=20?= =?UTF-8?q?=E6=94=AF=E6=8C=81=E5=BE=AE=E6=9C=8D=E5=8A=A1=E8=87=AA=E5=8A=A8?= =?UTF-8?q?=E6=B3=A8=E5=86=8C=E5=8F=91=E7=8E=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../config/SpringDocConfiguration.java | 129 ++++++++++-------- 1 file changed, 69 insertions(+), 60 deletions(-) diff --git a/pigx-gateway/src/main/java/com/pig4cloud/pigx/gateway/config/SpringDocConfiguration.java b/pigx-gateway/src/main/java/com/pig4cloud/pigx/gateway/config/SpringDocConfiguration.java index e262d5c58..fe4cd2303 100644 --- a/pigx-gateway/src/main/java/com/pig4cloud/pigx/gateway/config/SpringDocConfiguration.java +++ b/pigx-gateway/src/main/java/com/pig4cloud/pigx/gateway/config/SpringDocConfiguration.java @@ -1,22 +1,27 @@ package com.pig4cloud.pigx.gateway.config; -import cn.hutool.core.util.StrUtil; -import lombok.Data; +import com.alibaba.nacos.client.naming.event.InstancesChangeEvent; +import com.alibaba.nacos.common.notify.Event; +import com.alibaba.nacos.common.notify.NotifyCenter; +import com.alibaba.nacos.common.notify.listener.Subscriber; +import com.alibaba.nacos.common.utils.StringUtils; import lombok.RequiredArgsConstructor; -import org.springdoc.core.GroupedOpenApi; -import org.springdoc.core.SwaggerUiConfigParameters; +import org.springdoc.core.AbstractSwaggerUiConfigProperties; +import org.springdoc.core.SwaggerUiConfigProperties; +import org.springframework.beans.factory.InitializingBean; import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty; -import org.springframework.boot.context.properties.ConfigurationProperties; -import org.springframework.cloud.client.ServiceInstance; import org.springframework.cloud.client.discovery.DiscoveryClient; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.springframework.context.annotation.Lazy; -import org.springframework.stereotype.Component; +import org.springframework.core.io.Resource; +import org.springframework.web.reactive.resource.ResourceResolverChain; +import org.springframework.web.server.ServerWebExchange; +import reactor.core.publisher.Mono; -import java.util.ArrayList; import java.util.List; -import java.util.Map; +import java.util.Set; +import java.util.stream.Collectors; /** * @author lengleng @@ -26,60 +31,64 @@ import java.util.Map; */ @RequiredArgsConstructor @Configuration(proxyBeanMethods = false) -public class SpringDocConfiguration { +@ConditionalOnProperty(value = "springdoc.api-docs.enabled", matchIfMissing = true) +public class SpringDocConfiguration implements InitializingBean { + + private final SwaggerUiConfigProperties swaggerUiConfigProperties; private final DiscoveryClient discoveryClient; - @Bean - @Lazy(false) - @ConditionalOnProperty(name = "springdoc.api-docs.enabled", matchIfMissing = true) - public List apis(SwaggerUiConfigParameters swaggerUiConfigParameters) { - List groups = new ArrayList<>(); - - for (String serviceId : discoveryClient.getServices()) { - for (ServiceInstance instance : discoveryClient.getInstances(serviceId)) { - String doc = instance.getMetadata().get("spring-doc"); - if (StrUtil.isNotBlank(doc)) { - swaggerUiConfigParameters.addGroup(doc, serviceId); - } - } - } - return groups; - - } - - @Data - @Component - @ConfigurationProperties("swagger") - public class SwaggerDocProperties { - - private Map services; - - /** - * 认证参数 - */ - private SwaggerBasic basic = new SwaggerBasic(); - - @Data - public class SwaggerBasic { - - /** - * 是否开启 basic 认证 - */ - private Boolean enabled; - - /** - * 用户名 - */ - private String username; - - /** - * 密码 - */ - private String password; - - } - + /** + * 在初始化后调用的方法,用于注册SwaggerDocRegister订阅器 + */ + @Override + public void afterPropertiesSet() { + SwaggerDocRegister swaggerDocRegister = new SwaggerDocRegister(swaggerUiConfigProperties, discoveryClient); + // 手动调用一次,避免监听事件掉线问题 + swaggerDocRegister.onEvent(null); + NotifyCenter.registerSubscriber(swaggerDocRegister); + } + +} + +/** + * Swagger文档注册器,继承自Subscriber + */ +@RequiredArgsConstructor +class SwaggerDocRegister extends Subscriber { + + private final SwaggerUiConfigProperties swaggerUiConfigProperties; + + private final DiscoveryClient discoveryClient; + + /** + * 事件回调方法,处理InstancesChangeEvent事件 + * @param event 事件对象 + */ + @Override + public void onEvent(InstancesChangeEvent event) { + Set swaggerUrlSet = discoveryClient.getServices() + .stream() + .flatMap(serviceId -> discoveryClient.getInstances(serviceId).stream()) + .filter(instance -> StringUtils.isNotBlank(instance.getMetadata().get("spring-doc"))) + .map(instance -> { + AbstractSwaggerUiConfigProperties.SwaggerUrl swaggerUrl = new AbstractSwaggerUiConfigProperties.SwaggerUrl(); + swaggerUrl.setName(instance.getServiceId()); + swaggerUrl.setUrl(String.format("/%s/v3/api-docs", instance.getMetadata().get("spring-doc"))); + return swaggerUrl; + }) + .collect(Collectors.toSet()); + + swaggerUiConfigProperties.setUrls(swaggerUrlSet); + } + + /** + * 订阅类型方法,返回订阅的事件类型 + * @return 订阅的事件类型 + */ + @Override + public Class subscribeType() { + return InstancesChangeEvent.class; } }