diff --git a/zero-ecosystem/zero-boot/zero-boot-full-actor/pom.xml b/zero-ecosystem/zero-boot/zero-boot-full-actor/pom.xml index 5ede905de817233db7539f5bda6319c0f39dd68f..55481765e39683c4ca6a284c72a1e45df2d8b9e2 100644 --- a/zero-ecosystem/zero-boot/zero-boot-full-actor/pom.xml +++ b/zero-ecosystem/zero-boot/zero-boot-full-actor/pom.xml @@ -31,6 +31,10 @@ - liquibase - security --> + + io.zerows + zero-plugins-swagger + io.zerows zero-plugins-trash @@ -133,10 +137,10 @@ io.zerows zero-plugins-integration-wechat - - io.zerows - zero-plugins-integration-feign - + + + + io.zerows zero-plugins-office-excel diff --git a/zero-ecosystem/zero-boot/zero-boot-mini-actor/src/main/java/io/zerows/epoch/VertxApplication.java b/zero-ecosystem/zero-boot/zero-boot-mini-actor/src/main/java/io/zerows/epoch/VertxApplication.java index 2cb8559c4e120836fd9650424fe47bb6540b505f..0331bd98b8970c59188d53bc25784d3b65a024b3 100644 --- a/zero-ecosystem/zero-boot/zero-boot-mini-actor/src/main/java/io/zerows/epoch/VertxApplication.java +++ b/zero-ecosystem/zero-boot/zero-boot-mini-actor/src/main/java/io/zerows/epoch/VertxApplication.java @@ -9,6 +9,7 @@ import io.vertx.core.eventbus.EventBusOptions; import io.vertx.core.http.HttpServerOptions; import io.zerows.cortex.AxisDynamicFactory; import io.zerows.cortex.AxisSockFactory; +import io.zerows.cortex.AxisSwaggerFactory; import io.zerows.cortex.management.StoreVertx; import io.zerows.cortex.metadata.RunRoute; import io.zerows.cortex.metadata.RunServer; @@ -113,6 +114,7 @@ public class VertxApplication { WallProvider.class, // 安全提供者组件 FactoryDBAsync.class, // 异步DBE AxisSockFactory.class, // WebSocket + AxisSwaggerFactory.class, //Swagger AxisDynamicFactory.class // 动态路由 ); diff --git a/zero-ecosystem/zero-epoch/zero-epoch-cosmic/src/main/java/io/zerows/cosmic/bootstrap/AxisSwagger.java b/zero-ecosystem/zero-epoch/zero-epoch-cosmic/src/main/java/io/zerows/cosmic/bootstrap/AxisSwagger.java new file mode 100644 index 0000000000000000000000000000000000000000..23c16fa33da9fd003b815a25e9b762a96456c908 --- /dev/null +++ b/zero-ecosystem/zero-epoch/zero-epoch-cosmic/src/main/java/io/zerows/cosmic/bootstrap/AxisSwagger.java @@ -0,0 +1,42 @@ +package io.zerows.cosmic.bootstrap; + +import io.zerows.cortex.AxisSwaggerFactory; +import io.zerows.cortex.metadata.RunServer; +import io.zerows.cortex.sdk.Axis; +import io.zerows.specification.development.compiled.HBundle; +import io.zerows.spi.HPI; +import lombok.extern.slf4j.Slf4j; +import java.util.Objects; +import java.util.concurrent.atomic.AtomicBoolean; + +/** + * @author lang : 2025-01-XX + */ +@Slf4j +public class AxisSwagger implements Axis { + + private static final AtomicBoolean LOG_FACTORY_NULL = new AtomicBoolean(false); + private static final AtomicBoolean LOG_ENABLED = new AtomicBoolean(false); + private static final AtomicBoolean LOG_DISABLED = new AtomicBoolean(false); + + @Override + public void mount(RunServer server, HBundle bundle) { + final AxisSwaggerFactory factory = HPI.findOverwrite(AxisSwaggerFactory.class); + if (Objects.isNull(factory)) { + // 没有部署,无法找到工厂类(日志只打印一次) + if (LOG_FACTORY_NULL.compareAndSet(false, true)) { + log.info("[ ZERO ] ( Swagger ) ⚠️ SPI 组件 AxisSwaggerFactory 为 null,Swagger 功能禁用!"); + } + return; + } + if (factory.isEnabled(bundle, server)) { + if (LOG_ENABLED.compareAndSet(false, true)) { + log.info("[ ZERO ] ( Swagger ) Swagger 功能启动成功!,登录地址:http://"+server.name()+"/docs/#/"); + } + } else { + if (LOG_DISABLED.compareAndSet(false, true)) { + log.warn("[ ZERO ] ( Swagger ) 功能被配置禁用,请检查配置或联系管理员!"); + } + } + } +} diff --git a/zero-ecosystem/zero-epoch/zero-epoch-cosmic/src/main/java/io/zerows/cosmic/handler/ZeroHttpAgent.java b/zero-ecosystem/zero-epoch/zero-epoch-cosmic/src/main/java/io/zerows/cosmic/handler/ZeroHttpAgent.java index b8998c1e93475eb9da1ee6294e7dadc1723fc06a..7c1950db97b956aecc212efb1ff3bf39958ad330 100644 --- a/zero-ecosystem/zero-epoch/zero-epoch-cosmic/src/main/java/io/zerows/cosmic/handler/ZeroHttpAgent.java +++ b/zero-ecosystem/zero-epoch/zero-epoch-cosmic/src/main/java/io/zerows/cosmic/handler/ZeroHttpAgent.java @@ -13,6 +13,7 @@ import io.zerows.cosmic.bootstrap.AxisFilter; import io.zerows.cosmic.bootstrap.AxisMeasure; import io.zerows.cosmic.bootstrap.AxisSecure; import io.zerows.cosmic.bootstrap.AxisStart; +import io.zerows.cosmic.bootstrap.AxisSwagger; import io.zerows.epoch.annotations.Agent; import io.zerows.specification.development.compiled.HBundle; import io.zerows.spi.HPI; @@ -45,16 +46,15 @@ public class ZeroHttpAgent extends AbstractVerticle { * - Cors */ Axis.ofOr(AxisCommon.class).mount(runServer, bundle); - /* - * 02. 安全 + * 03. 安全 * - 401 Authentication * - 403 Authorization */ Axis.ofOr(AxisSecure.class).mount(runServer, bundle); /* - * 03. 监控 + * 04. 监控 * - Module Monitor * - Service Monitor * - Gateway Monitor @@ -62,24 +62,28 @@ public class ZeroHttpAgent extends AbstractVerticle { Axis.ofOr(AxisMeasure.class).mount(runServer, bundle); /* - * 04. JSR-340 + * 05. JSR-340 * - Filter * - Listener */ Axis.ofOr(AxisFilter.class).mount(runServer, bundle); /* - * 05. 主流程 + * 06. 主流程 */ Axis.ofOr(AxisEvent.class).mount(runServer, bundle); /* - * 06. Extension 扩展路由 + * 07. Extension 扩展路由 */ Axis.ofOr(AxisExtension.class).mount(runServer, bundle); + /* + * 08. Swagger 挂载 + */ + Axis.ofOr(AxisSwagger.class).mount(runServer, bundle); /* - * 07. 启动完成监听 + * 09. 启动完成监听 */ Axis.ofOr(AxisStart.class).mount(runServer, bundle); diff --git a/zero-ecosystem/zero-epoch/zero-epoch-focus/src/main/java/io/zerows/cortex/AxisSwaggerFactory.java b/zero-ecosystem/zero-epoch/zero-epoch-focus/src/main/java/io/zerows/cortex/AxisSwaggerFactory.java new file mode 100644 index 0000000000000000000000000000000000000000..dc09cab9dcdc4bba755973a6c8877b42d973af02 --- /dev/null +++ b/zero-ecosystem/zero-epoch/zero-epoch-focus/src/main/java/io/zerows/cortex/AxisSwaggerFactory.java @@ -0,0 +1,34 @@ +package io.zerows.cortex; + +import io.zerows.cortex.metadata.RunServer; +import io.zerows.cortex.sdk.Axis; +import io.zerows.specification.development.compiled.HBundle; + +/** + * WebSocket 路由管理器工厂,用于提取路由管理器专用,不同环境的设计如下: + *

+ *     非 OSGI 环境中
+ *     - 1. 直接加载 SPI 提取 AxisSockFactory 的实现
+ *       2. 调用 AxisSockFactory 实现中的方法提取 OAxis 路由挂载器
+ *     OSGI 环境中
+ *     - 1. AxisSockFactory 实现启动时直接注册到 FactorySockManager 中,由它来查找对应的实现,Service 调用
+ *       2. 调用 AxisSockFactory 实现中的方法提取 OAxis 路由挂载器
+ * 
+ * + * @author lang : 2024-06-26 + */ +public interface AxisSwaggerFactory { + /** + * 提取路由挂载器 + * + * @return 返回路由挂载器 + */ + Axis getAxis(); + + /** + * 判断是否启用了 Sock 功能 + * + * @return 如果启用了则直接返回 true + */ + boolean isEnabled(HBundle owner,RunServer runServer); +} diff --git a/zero-ecosystem/zero-plugins-equip/zero-plugins-swagger/pom.xml b/zero-ecosystem/zero-plugins-equip/zero-plugins-swagger/pom.xml index 749e1079505b02cda738ec5cf1f91aa61e9a3ae3..a5a2c6db7a445545da9cf5257aa6b62c5bff4db5 100644 --- a/zero-ecosystem/zero-plugins-equip/zero-plugins-swagger/pom.xml +++ b/zero-ecosystem/zero-plugins-equip/zero-plugins-swagger/pom.xml @@ -17,10 +17,10 @@ vertx-web-api-contract
- - io.zerows - zero-plugins-integration-feign - + + + + io.zerows zero-epoch-setting @@ -48,6 +48,10 @@ classgraph 4.8.158 + + io.zerows + zero-epoch-cosmic + diff --git a/zero-ecosystem/zero-plugins-equip/zero-plugins-swagger/src/main/java/io/zerows/plugins/swagger/MainVerticle.java b/zero-ecosystem/zero-plugins-equip/zero-plugins-swagger/src/main/java/io/zerows/plugins/swagger/MainVerticle.java deleted file mode 100644 index f11d467df10c730b3b4721f8ff1b022a16ec9773..0000000000000000000000000000000000000000 --- a/zero-ecosystem/zero-plugins-equip/zero-plugins-swagger/src/main/java/io/zerows/plugins/swagger/MainVerticle.java +++ /dev/null @@ -1,41 +0,0 @@ -package io.zerows.plugins.swagger; - -import io.vertx.config.ConfigRetriever; -import io.vertx.core.AbstractVerticle; -import io.vertx.core.Promise; -import io.zerows.epoch.annotations.Worker; -import io.zerows.platform.constant.VValue; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -@Worker(instances = VValue.SINGLE) -public class MainVerticle extends AbstractVerticle { - private static final Logger logger = LoggerFactory.getLogger(MainVerticle.class); - - @Override - public void start(final Promise startPromise) { - final ConfigRetriever retriever = ConfigRetriever.create(this.vertx); - retriever.getConfig().onComplete(config -> { - // if (config.succeeded()) { - // final Boolean EnvRocketMq = config.result().getBoolean("Z_ENV_SWAGGER"); - // if (EnvRocketMq) { - // final Router router = Router.router(this.vertx); - // - // // 挂载 Swagger 插件 - // SwaggerPlugin.mount(router, this.vertx); - // - // this.vertx.createHttpServer() - // .requestHandler(router) - // .listen(8888) - // .onSuccess(server -> { - // logger.info("✅ 服务启动成功: http://localhost:8888/docs/index.html"); - // startPromise.complete(); - // }) - // .onFailure(startPromise::fail); - // } else { - // logger.info("未启动Swagger"); - // } - // } - }); - } -} diff --git a/zero-ecosystem/zero-plugins-equip/zero-plugins-swagger/src/main/java/io/zerows/plugins/swagger/SwaggerActor.java b/zero-ecosystem/zero-plugins-equip/zero-plugins-swagger/src/main/java/io/zerows/plugins/swagger/SwaggerActor.java new file mode 100644 index 0000000000000000000000000000000000000000..377c77efa70bc80b6c6a50ba977b2d2adfc67b7d --- /dev/null +++ b/zero-ecosystem/zero-plugins-equip/zero-plugins-swagger/src/main/java/io/zerows/plugins/swagger/SwaggerActor.java @@ -0,0 +1,39 @@ +package io.zerows.plugins.swagger; + +import io.swagger.v3.oas.models.OpenAPI; +import io.vertx.core.Future; +import io.vertx.core.Vertx; +import io.zerows.component.module.AbstractHActor; +import io.zerows.epoch.annotations.Actor; +import io.zerows.plugins.swagger.management.OCacheSwagger; +import io.zerows.specification.configuration.HConfig; +import io.zerows.spi.HPI; +import lombok.extern.slf4j.Slf4j; + +import java.util.Set; + +/** + * @author lang : 2025-10-17 + */ +@Actor(value = "swagger") +@Slf4j +public class SwaggerActor extends AbstractHActor { + + @Override + protected Future startAsync(final HConfig config, final Vertx vertxRef) { + this.vLog("[ Swagger ] SwaggerActor 正在扫描接口类,vertx = {}", vertxRef.hashCode()); + + // Step1: 扫描接口类 + final Set> handlerClasses = SwaggerScanner.scan(); + + // Step2: 生成 OpenAPI 文档 + final OpenAPI openAPI = SwaggerOpenAPI.generate(handlerClasses); + + // Step3: 存入缓存 + final SwaggerData swaggerData = new SwaggerData(handlerClasses, openAPI); + OCacheSwagger.of(HPI.findBundle(this.getClass())).add(swaggerData); + //键分离 vertx 命名改了 + this.vLog("[ Swagger ] ✅ SwaggerActor 已成功扫描完成,扫描到 {} 个处理器类", handlerClasses.size()); + return Future.succeededFuture(Boolean.TRUE); + } +} diff --git a/zero-ecosystem/zero-plugins-equip/zero-plugins-swagger/src/main/java/io/zerows/plugins/swagger/SwaggerAnnotationScanner.java b/zero-ecosystem/zero-plugins-equip/zero-plugins-swagger/src/main/java/io/zerows/plugins/swagger/SwaggerAnnotationScanner.java deleted file mode 100644 index e606c3d16a9c0b16ca163ee60859afe0a2d302ee..0000000000000000000000000000000000000000 --- a/zero-ecosystem/zero-plugins-equip/zero-plugins-swagger/src/main/java/io/zerows/plugins/swagger/SwaggerAnnotationScanner.java +++ /dev/null @@ -1,71 +0,0 @@ -package io.zerows.plugins.swagger; - -import io.swagger.v3.oas.annotations.Operation; -import io.swagger.v3.oas.annotations.Parameter; -import io.swagger.v3.oas.annotations.media.Schema; -import io.swagger.v3.oas.annotations.parameters.RequestBody; -import io.swagger.v3.oas.annotations.responses.ApiResponse; -import io.zerows.epoch.management.OCacheClass; -import jakarta.ws.rs.DELETE; -import jakarta.ws.rs.GET; -import jakarta.ws.rs.PATCH; -import jakarta.ws.rs.POST; -import jakarta.ws.rs.PUT; -import jakarta.ws.rs.Path; - -import java.lang.reflect.Method; -import java.util.HashSet; -import java.util.Set; - -public class SwaggerAnnotationScanner { - - public static Set> scan() { - final Set> allClasses = OCacheClass.entireValue(); - final Set> interfaces = new HashSet<>(); - - for (final Class cls : allClasses) { - if (!cls.isInterface()) { - continue; - } - - final boolean hasPath = cls.isAnnotationPresent(Path.class); - boolean hasOperation = false; - - for (final Method method : cls.getDeclaredMethods()) { - if (method.isAnnotationPresent(Path.class) || - method.isAnnotationPresent(GET.class) || - method.isAnnotationPresent(POST.class) || - method.isAnnotationPresent(PUT.class) || - method.isAnnotationPresent(DELETE.class) || - method.isAnnotationPresent(PATCH.class) || - method.isAnnotationPresent(Operation.class) || - method.isAnnotationPresent(RequestBody.class) || - method.isAnnotationPresent(ApiResponse.class) || - method.isAnnotationPresent(Parameter.class) || - method.isAnnotationPresent(Schema.class) || - hasParameterAnnotations(method)) { - hasOperation = true; - break; - } - } - - if (hasPath && hasOperation) { - interfaces.add(cls); - } - } - - return interfaces; - } - - /** - * 检查方法参数是否有 Swagger 注解 - */ - private static boolean hasParameterAnnotations(final Method method) { - for (final java.lang.reflect.Parameter param : method.getParameters()) { - if (param.isAnnotationPresent(Parameter.class)) { - return true; - } - } - return false; - } -} diff --git a/zero-ecosystem/zero-plugins-equip/zero-plugins-swagger/src/main/java/io/zerows/plugins/swagger/SwaggerData.java b/zero-ecosystem/zero-plugins-equip/zero-plugins-swagger/src/main/java/io/zerows/plugins/swagger/SwaggerData.java new file mode 100644 index 0000000000000000000000000000000000000000..f9289f9eee022b3c106fdd4773794cdc4444ccf0 --- /dev/null +++ b/zero-ecosystem/zero-plugins-equip/zero-plugins-swagger/src/main/java/io/zerows/plugins/swagger/SwaggerData.java @@ -0,0 +1,34 @@ +package io.zerows.plugins.swagger; + +import io.swagger.v3.oas.models.OpenAPI; +import lombok.Data; + +import java.io.Serializable; +import java.util.Set; + +/** + * Swagger 数据包装类,用于缓存处理器接口类和 OpenAPI 文档 + * + * @author lang : 2025-10-17 + */ +@Data +public class SwaggerData implements Serializable { + /** + * 扫描到的所有处理器接口类(标注了 @Path 的类) + */ + private Set> handlerClasses; + + /** + * 生成的 OpenAPI 文档对象 + */ + private OpenAPI openAPI; + + public SwaggerData() { + } + + public SwaggerData(final Set> handlerClasses, final OpenAPI openAPI) { + this.handlerClasses = handlerClasses; + this.openAPI = openAPI; + } +} + diff --git a/zero-ecosystem/zero-plugins-equip/zero-plugins-swagger/src/main/java/io/zerows/plugins/swagger/OpenApiGenerator.java b/zero-ecosystem/zero-plugins-equip/zero-plugins-swagger/src/main/java/io/zerows/plugins/swagger/SwaggerOpenAPI.java similarity index 97% rename from zero-ecosystem/zero-plugins-equip/zero-plugins-swagger/src/main/java/io/zerows/plugins/swagger/OpenApiGenerator.java rename to zero-ecosystem/zero-plugins-equip/zero-plugins-swagger/src/main/java/io/zerows/plugins/swagger/SwaggerOpenAPI.java index db3288582f8e46156c15ff8b8f3699b255212422..c5b31ab459411e24b38178ba03ee1d5270a4725b 100644 --- a/zero-ecosystem/zero-plugins-equip/zero-plugins-swagger/src/main/java/io/zerows/plugins/swagger/OpenApiGenerator.java +++ b/zero-ecosystem/zero-plugins-equip/zero-plugins-swagger/src/main/java/io/zerows/plugins/swagger/SwaggerOpenAPI.java @@ -30,7 +30,7 @@ import java.util.Set; * - @Tag: 标签分组 * - @Schema: 数据模型描述 */ -public class OpenApiGenerator { +class SwaggerOpenAPI { /** * 生成 OpenAPI 文档对象。 diff --git a/zero-ecosystem/zero-plugins-equip/zero-plugins-swagger/src/main/java/io/zerows/plugins/swagger/SwaggerPlugin.java b/zero-ecosystem/zero-plugins-equip/zero-plugins-swagger/src/main/java/io/zerows/plugins/swagger/SwaggerPlugin.java index b9a49cca033dba6c387aa930904860d5db7c95e3..24cd97b42da06f1ffae7e6f08ac747c3183c64c3 100644 --- a/zero-ecosystem/zero-plugins-equip/zero-plugins-swagger/src/main/java/io/zerows/plugins/swagger/SwaggerPlugin.java +++ b/zero-ecosystem/zero-plugins-equip/zero-plugins-swagger/src/main/java/io/zerows/plugins/swagger/SwaggerPlugin.java @@ -1,18 +1,47 @@ package io.zerows.plugins.swagger; -import io.vertx.core.Vertx; +import io.swagger.v3.oas.models.OpenAPI; import io.vertx.ext.web.Router; +import io.zerows.cortex.AxisSwaggerFactory; +import io.zerows.cortex.metadata.RunServer; +import io.zerows.cortex.sdk.Axis; +import io.zerows.epoch.configuration.NodeNetwork; +import io.zerows.epoch.configuration.NodeStore; +import io.zerows.plugins.swagger.management.OCacheSwagger; +import io.zerows.specification.configuration.HConfig; +import io.zerows.specification.configuration.HSetting; +import io.zerows.specification.development.compiled.HBundle; -public class SwaggerPlugin { - public static void mount(Router router, Vertx vertx) { - // Step1: 扫描接口类 - var handlerClasses = SwaggerAnnotationScanner.scan(); +public class SwaggerPlugin implements AxisSwaggerFactory { - // Step2: 生成 OpenAPI 文档 - var openAPI = OpenApiGenerator.generate(handlerClasses); + @Override + public Axis getAxis() { + return null; + } - // Step3: 构造路由并挂载 - SwaggerRouteBuilder.mount(router, openAPI); + @Override + public boolean isEnabled(final HBundle owner, final RunServer runServer) { + final NodeNetwork nodeNetwork = NodeStore.ofNetwork(); + final HSetting setting = nodeNetwork.setting(); + final HConfig swaggerConfig = setting.extension("swagger"); + if(swaggerConfig==null){ + return false; + } + final Boolean swagger = swaggerConfig.options().getBoolean("enabled"); + if(swagger==null|| !swagger){ + return false; + }else { + final Router router = runServer.refRouter(); + // 获取第一个可用的 Swagger 数据 + final SwaggerData data = OCacheSwagger.entireFirst(); + if (data != null) { + final OpenAPI openAPI = data.getOpenAPI(); + // Step3: 构造路由并挂载 + SwaggerRouteMount.mount(router, openAPI); + } + return true; + } } + } diff --git a/zero-ecosystem/zero-plugins-equip/zero-plugins-swagger/src/main/java/io/zerows/plugins/swagger/SwaggerRouteBuilder.java b/zero-ecosystem/zero-plugins-equip/zero-plugins-swagger/src/main/java/io/zerows/plugins/swagger/SwaggerRouteMount.java similarity index 91% rename from zero-ecosystem/zero-plugins-equip/zero-plugins-swagger/src/main/java/io/zerows/plugins/swagger/SwaggerRouteBuilder.java rename to zero-ecosystem/zero-plugins-equip/zero-plugins-swagger/src/main/java/io/zerows/plugins/swagger/SwaggerRouteMount.java index 7bb51b8409cae57893cd18921736620945db652d..04f61a2ef405423cabc69c5f480047a6f6d2f6f4 100644 --- a/zero-ecosystem/zero-plugins-equip/zero-plugins-swagger/src/main/java/io/zerows/plugins/swagger/SwaggerRouteBuilder.java +++ b/zero-ecosystem/zero-plugins-equip/zero-plugins-swagger/src/main/java/io/zerows/plugins/swagger/SwaggerRouteMount.java @@ -5,7 +5,7 @@ import io.swagger.v3.oas.models.OpenAPI; import io.vertx.ext.web.Router; import io.vertx.ext.web.handler.StaticHandler; -public class SwaggerRouteBuilder { +class SwaggerRouteMount { public static void mount(Router router, OpenAPI openAPI) { // Static UI diff --git a/zero-ecosystem/zero-plugins-equip/zero-plugins-swagger/src/main/java/io/zerows/plugins/swagger/SwaggerScanner.java b/zero-ecosystem/zero-plugins-equip/zero-plugins-swagger/src/main/java/io/zerows/plugins/swagger/SwaggerScanner.java new file mode 100644 index 0000000000000000000000000000000000000000..eb0cc26903f3994b60ec56344a7d2536be3b8f56 --- /dev/null +++ b/zero-ecosystem/zero-plugins-equip/zero-plugins-swagger/src/main/java/io/zerows/plugins/swagger/SwaggerScanner.java @@ -0,0 +1,94 @@ +package io.zerows.plugins.swagger; + +import io.swagger.v3.oas.annotations.Operation; +import io.swagger.v3.oas.annotations.Parameter; +import io.swagger.v3.oas.annotations.media.Schema; +import io.swagger.v3.oas.annotations.parameters.RequestBody; +import io.swagger.v3.oas.annotations.responses.ApiResponse; +import io.zerows.epoch.management.OCacheClass; +import jakarta.ws.rs.DELETE; +import jakarta.ws.rs.GET; +import jakarta.ws.rs.PATCH; +import jakarta.ws.rs.POST; +import jakarta.ws.rs.PUT; +import jakarta.ws.rs.Path; + +import java.lang.reflect.Method; +import java.util.HashSet; +import java.util.Set; + +class SwaggerScanner { + + public static Set> scan() { + try { + final Set> allClasses = OCacheClass.entireValue(); + final Set> interfaces = new HashSet<>(); + + for (final Class cls : allClasses) { + try { + if (!cls.isInterface()) { + continue; + } + + final boolean hasPath = cls.isAnnotationPresent(Path.class); + boolean hasOperation = false; + + final Method[] methods = cls.getDeclaredMethods(); + for (final Method method : methods) { + try { + if (method.isAnnotationPresent(Path.class) || + method.isAnnotationPresent(GET.class) || + method.isAnnotationPresent(POST.class) || + method.isAnnotationPresent(PUT.class) || + method.isAnnotationPresent(DELETE.class) || + method.isAnnotationPresent(PATCH.class) || + method.isAnnotationPresent(Operation.class) || + method.isAnnotationPresent(RequestBody.class) || + method.isAnnotationPresent(ApiResponse.class) || + method.isAnnotationPresent(Parameter.class) || + method.isAnnotationPresent(Schema.class) || + hasParameterAnnotations(method)) { + hasOperation = true; + break; + } + } catch (Exception e) { + // 跳过有问题的单个方法 + System.err.println("Warning: Failed to process method " + method.getName() + " in class " + cls.getName() + ": " + e.getMessage()); + } + } + + if (hasPath && hasOperation) { + interfaces.add(cls); + } + } catch (Exception e) { + // 跳过有问题的类 + System.err.println("Warning: Failed to process class " + cls.getName() + ": " + e.getMessage()); + } + } + + return interfaces; + } catch (Exception e) { + System.err.println("Error during Swagger annotation scanning: " + e.getMessage()); + return new HashSet<>(); + } + } + + /** + * 检查方法参数是否有 Swagger 注解 + */ + private static boolean hasParameterAnnotations(final Method method) { + try { + // 使用 try-catch 避免反射操作阻塞 + final java.lang.reflect.Parameter[] parameters = method.getParameters(); + for (final java.lang.reflect.Parameter param : parameters) { + if (param.isAnnotationPresent(Parameter.class)) { + return true; + } + } + } catch (Exception e) { + // 如果反射操作失败,跳过参数检查 + System.err.println("Warning: Failed to get parameters for method " + method.getName() + ": " + e.getMessage()); + } + return false; + } +} diff --git a/zero-ecosystem/zero-plugins-equip/zero-plugins-swagger/src/main/java/io/zerows/plugins/swagger/management/OCacheSwagger.java b/zero-ecosystem/zero-plugins-equip/zero-plugins-swagger/src/main/java/io/zerows/plugins/swagger/management/OCacheSwagger.java new file mode 100644 index 0000000000000000000000000000000000000000..e020dc6896c97aaa400452b1c84f1b28dafd589e --- /dev/null +++ b/zero-ecosystem/zero-plugins-equip/zero-plugins-swagger/src/main/java/io/zerows/plugins/swagger/management/OCacheSwagger.java @@ -0,0 +1,54 @@ +package io.zerows.plugins.swagger.management; + +import io.r2mo.typed.cc.Cc; +import io.zerows.plugins.swagger.SwaggerData; +import io.zerows.platform.management.OCache; +import io.zerows.specification.development.compiled.HBundle; + +import java.util.Objects; +import java.util.Set; +import java.util.stream.Collectors; + +/** + * Swagger 缓存接口,用于存储 Swagger 相关的数据 + * + * @author lang : 2025-10-17 + */ +public interface OCacheSwagger extends OCache { + Cc CC_SKELETON = Cc.open(); + + static OCacheSwagger of(final HBundle bundle) { + final String cacheKey = HBundle.id(bundle, OCacheSwaggerAmbiguity.class); + return CC_SKELETON.pick(() -> new OCacheSwaggerAmbiguity(bundle), cacheKey); + } + + static OCacheSwagger of() { + return of(null); + } + + /** + * 获取所有 Bundle 中的 Swagger 数据 + * + * @return 所有 Swagger 数据的集合 + */ + static Set entireValue() { + return CC_SKELETON.values().stream() + .map(OCache::value) + .filter(Objects::nonNull) + .collect(Collectors.toSet()); + } + + /** + * 获取第一个可用的 Swagger 数据(通常全局只有一个) + * + * @return Swagger 数据,如果没有则返回 null + */ + static SwaggerData entireFirst() { + return CC_SKELETON.values().stream() + .map(OCache::value) + .filter(Objects::nonNull) + .findFirst() + .orElse(null); + } +} + diff --git a/zero-ecosystem/zero-plugins-equip/zero-plugins-swagger/src/main/java/io/zerows/plugins/swagger/management/OCacheSwaggerAmbiguity.java b/zero-ecosystem/zero-plugins-equip/zero-plugins-swagger/src/main/java/io/zerows/plugins/swagger/management/OCacheSwaggerAmbiguity.java new file mode 100644 index 0000000000000000000000000000000000000000..7f1b07fca04575d58e05117b977e21b9a3dc8ae9 --- /dev/null +++ b/zero-ecosystem/zero-plugins-equip/zero-plugins-swagger/src/main/java/io/zerows/plugins/swagger/management/OCacheSwaggerAmbiguity.java @@ -0,0 +1,38 @@ +package io.zerows.plugins.swagger.management; + +import io.zerows.plugins.swagger.SwaggerData; +import io.zerows.platform.management.AbstractAmbiguity; +import io.zerows.specification.development.compiled.HBundle; + +/** + * Swagger 缓存实现类 + * + * @author lang : 2025-10-17 + */ +class OCacheSwaggerAmbiguity extends AbstractAmbiguity implements OCacheSwagger { + private SwaggerData swaggerData; + + OCacheSwaggerAmbiguity(final HBundle bundle) { + super(bundle); + } + + @Override + public SwaggerData value() { + return this.swaggerData; + } + + @Override + public OCacheSwagger add(final SwaggerData data) { + this.swaggerData = data; + return this; + } + + @Override + public OCacheSwagger remove(final SwaggerData data) { + if (this.swaggerData != null && this.swaggerData.equals(data)) { + this.swaggerData = null; + } + return this; + } +} + diff --git a/zero-ecosystem/zero-plugins-equip/zero-plugins-swagger/src/main/resources/META-INF/services/io.zerows.cortex.AxisSwaggerFactory b/zero-ecosystem/zero-plugins-equip/zero-plugins-swagger/src/main/resources/META-INF/services/io.zerows.cortex.AxisSwaggerFactory new file mode 100644 index 0000000000000000000000000000000000000000..9c5aa0bd6e54ddac3e5446ea7a893bc5dcd009ad --- /dev/null +++ b/zero-ecosystem/zero-plugins-equip/zero-plugins-swagger/src/main/resources/META-INF/services/io.zerows.cortex.AxisSwaggerFactory @@ -0,0 +1 @@ +io.zerows.plugins.swagger.SwaggerPlugin diff --git a/zero-ecosystem/zero-plugins-extension/zero-extension-commerce-api/pom.xml b/zero-ecosystem/zero-plugins-extension/zero-extension-commerce-api/pom.xml index fabc7e08dacb00bb1571ddd3325f9050273b2830..2ac416cb3e890ad9280a4b128759634eb79a1efd 100644 --- a/zero-ecosystem/zero-plugins-extension/zero-extension-commerce-api/pom.xml +++ b/zero-ecosystem/zero-plugins-extension/zero-extension-commerce-api/pom.xml @@ -27,7 +27,7 @@ --> io.zerows - zero-extension-commerce-erp + zero-extension-erp-api ${project.version} diff --git a/zero-version/zero-version-plugins/pom.xml b/zero-version/zero-version-plugins/pom.xml index c4650758d16001d9ede1da1ea1aee8afca4bc801..1e98b252a5ffdda9e2bf4b22e53b248fe4950447 100644 --- a/zero-version/zero-version-plugins/pom.xml +++ b/zero-version/zero-version-plugins/pom.xml @@ -45,11 +45,11 @@ zero-plugins-integration-wechat ${zero.version} - - io.zerows - zero-plugins-integration-feign - ${zero.version} - + + + + + io.zerows