[ https://issues.apache.org/jira/browse/HBASE-28977?page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel&focusedCommentId=17898667#comment-17898667 ]
Dávid Paksy edited comment on HBASE-28977 at 11/15/24 3:46 PM: --------------------------------------------------------------- h2. In short *It does not work with our way of shading of JAX-RS libraries.* Maybe we could make it work if we would add swagger-core to our [https://github.com/apache/hbase-thirdparty] repository and shade it as well. But this may be too much effort compared to the value. h2. What is OpenAPI / Swagger {quote}*OpenAPI Specification* (formerly Swagger Specification) is an API description format for REST APIs. An OpenAPI file allows you to describe your entire API {quote} [https://swagger.io/docs/specification/v3_0/about/] Interesting parts for us: - [Swagger Core|https://github.com/swagger-api/swagger-core] – Java-related libraries for creating, consuming, and working with OpenAPI definitions. - [Swagger UI|https://github.com/swagger-api/swagger-ui] – renders OpenAPI definitions as interactive documentation. h2. Value Having the OpenAPI JSON / YAML file would allow: * developers to import the file to PostMan (REST client) and try HBase REST API quickly. * to generate REST API clients in the supported programming languages: [https://swagger.io/tools/open-source/open-source-integrations/] * render OpenAPI definitions as interactive (playground) web documentation page. h2. Manually create OpenAPI One option is to write the JSON / YAML file based on the [specification|https://swagger.io/docs/specification/v3_0/basic-structure/] but this is time consuming and then the file will have to maintained later when there are changes to the REST API (and likely to be forgotten). h2. Runtime integration If you add it to the JAX-RS Java project, it will add a servlet which can serve the OpenAPI JSON (or YAML) file based on the automatically detected the JAX-RS annotations (Path, GET, POST, DELETE, Produces, etc) in the application. (The OpenAPI JSON file could be used with [Swagger UI|https://github.com/swagger-api/swagger-ui] to render the interactive documentation.) Integration was based on: * [https://github.com/swagger-api/swagger-core/wiki/Swagger-2.X---Getting-started] * [https://github.com/swagger-api/swagger-core/wiki/Swagger-2.X---Integration-and-Configuration] * [https://anirtek.github.io/java/jetty/swagger/openapi/2021/06/12/Hooking-up-OpenAPI-with-Jetty.html] It can be seen in this PR how it is integrated: [https://github.com/PDavid/hbase/pull/1] Problem: When we add OpenAPI library and the servlet, we face with this: {code:java} 2024-11-15T15:32:33,436 WARN [qtp1989332276-50 {}] server.HttpChannel: /openapi java.lang.NoClassDefFoundError: javax/ws/rs/Path at io.swagger.v3.jaxrs2.Reader.read(Reader.java:285) ~[swagger-jaxrs2-2.2.25.jar:2.2.25] at io.swagger.v3.jaxrs2.Reader.read(Reader.java:199) ~[swagger-jaxrs2-2.2.25.jar:2.2.25] at io.swagger.v3.jaxrs2.Reader.read(Reader.java:228) ~[swagger-jaxrs2-2.2.25.jar:2.2.25] at io.swagger.v3.oas.integration.GenericOpenApiContext.read(GenericOpenApiContext.java:693) ~[swagger-integration-2.2.25.jar:2.2.25] at io.swagger.v3.jaxrs2.integration.OpenApiServlet.doGet(OpenApiServlet.java:55) ~[swagger-jaxrs2-2.2.25.jar:2.2.25] at javax.servlet.http.HttpServlet.service(HttpServlet.java:687) ~[javax.servlet-api-3.1.0.jar:3.1.0] at javax.servlet.http.HttpServlet.service(HttpServlet.java:790) ~[javax.servlet-api-3.1.0.jar:3.1.0] at org.apache.hbase.thirdparty.org.eclipse.jetty.servlet.ServletHolder.handle(ServletHolder.java:799) ~[hbase-shaded-jetty-4.1.9.jar:?] at org.apache.hbase.thirdparty.org.eclipse.jetty.servlet.ServletHandler$ChainEnd.doFilter(ServletHandler.java:1656) ~[hbase-shaded-jetty-4.1.9.jar:?] ... at org.apache.hbase.thirdparty.org.eclipse.jetty.util.thread.QueuedThreadPool$Runner.run(QueuedThreadPool.java:1034) ~[hbase-shaded-jetty-4.1.9.jar:?] at java.lang.Thread.run(Thread.java:840) ~[?:?] Caused by: java.lang.ClassNotFoundException: javax.ws.rs.Path at jdk.internal.loader.BuiltinClassLoader.loadClass(BuiltinClassLoader.java:641) ~[?:?] at jdk.internal.loader.ClassLoaders$AppClassLoader.loadClass(ClassLoaders.java:188) ~[?:?] at java.lang.ClassLoader.loadClass(ClassLoader.java:525) ~[?:?] ... 44 more {code} The OpenAPI / Swagger code directly depends on JAX-RS classes such as {{javax.ws.rs.Path}} but HBase REST uses shaded thirdparty version of these ({{{}org.apache.hbase.thirdparty.javax.ws.rs.Path{}}}). Even if we add the {{javax.ws.rs:javax.ws.rs-api}} library to the HBase REST project, the generated openapi JSON file will not contain, just the metadata (without any useful endpoints) because the OpenAPI / Swagger code only considers JAX-RS annotations. Also tried to add some Swagger annotations based on [https://github.com/swagger-api/swagger-core/wiki/Swagger-2.X]—Annotations but this did not help. There is a way to configure resource scanning [https://github.com/swagger-api/swagger-core/wiki/Swagger-2.X---Integration-and-Configuration#resource-scanning |https://github.com/swagger-api/swagger-core/wiki/Swagger-2.X---Integration-and-Configuration#resource-scanning]however all options only supports {{javax.ws.rs}} annotations - we could write our own but it is a lot of work. Maybe we could make it work if we would add swagger-core to our [https://github.com/apache/hbase-thirdparty] repository and shade it as well. This I did not yet tried. h2. Build-time integration There is a Swagger Maven plugin which can be added to the build which builds the file: {{swagger-maven-plugin}} ({*}since 2.0.5{*}): provides a maven plugin to resolve an OpenAPI definition at build time (using {{{}swagger-jaxrs2{}}}). Please see [module readme|https://github.com/swagger-api/swagger-core/tree/master/modules/swagger-maven-plugin/README.md] However adding it requires also adding the {{javax.ws.rs:javax.ws.rs-api}} library to the HBase REST project otherwise the build will fail: {code:java} [ERROR] Failed to execute goal io.swagger.core.v3:swagger-maven-plugin:2.2.25:resolve (default-cli) on project hbase-rest: Execution default-cli of goal io.swagger.core.v3:swagger-maven-plugin:2.2.25:resolve failed: A required class was missing while executing io.swagger.core.v3:swagger-maven-plugin:2.2.25:resolve: javax/ws/rs/Path {code} If the JAX-RS library is added, then the build will be successful but the same problem: the generated openapi JSON file will not contain, just the metadata (without any useful endpoints) because the OpenAPI / Swagger code only considers JAX-RS annotations. Also tried to add some Swagger annotations based on [https://github.com/swagger-api/swagger-core/wiki/Swagger-2.X]—Annotations but this did not help. was (Author: JIRAUSER306931): h2. In short *It does not work with our way of shading of JAX-RS libraries.* Maybe we could make it work if we would add swagger-core to our [https://github.com/apache/hbase-thirdparty] repository and shade it as well. But this may be too much effort compared to the value. h2. What is OpenAPI / Swagger {quote}*OpenAPI Specification* (formerly Swagger Specification) is an API description format for REST APIs. An OpenAPI file allows you to describe your entire API {quote} [https://swagger.io/docs/specification/v3_0/about/] Interesting parts for us: - [Swagger Core|https://github.com/swagger-api/swagger-core] – Java-related libraries for creating, consuming, and working with OpenAPI definitions. - [Swagger UI|https://github.com/swagger-api/swagger-ui] – renders OpenAPI definitions as interactive documentation. h2. Value Having the OpenAPI JSON / YAML file would allow: * developers to import the file to PostMan (REST client) and try HBase REST API quickly. * to generate REST API clients in the supported programming languages: [https://swagger.io/tools/open-source/open-source-integrations/] * render OpenAPI definitions as interactive (playground) web documentation page. h2. Manually create OpenAPI One option is to write the JSON / YAML file based on the [specification|https://swagger.io/docs/specification/v3_0/basic-structure/] but this is time consuming and then the file will have to maintained later when there are changes to the REST API (and likely to be forgotten). h2. Runtime integration If you add it to the JAX-RS Java project, it will add a servlet which can serve the OpenAPI JSON (or YAML) file based on the automatically detected the JAX-RS annotations (Path, GET, POST, DELETE, Produces, etc) in the application. (The OpenAPI JSON file could be used with [Swagger UI|https://github.com/swagger-api/swagger-ui] to render the interactive documentation.) Integration was based on: * [https://github.com/swagger-api/swagger-core/wiki/Swagger-2.X---Getting-started] * [https://github.com/swagger-api/swagger-core/wiki/Swagger-2.X---Integration-and-Configuration] * [https://anirtek.github.io/java/jetty/swagger/openapi/2021/06/12/Hooking-up-OpenAPI-with-Jetty.html] It can be seen in this PR how it is integrated: [https://github.com/PDavid/hbase/pull/1] Problem: When we add OpenAPI library and the servlet, we face with this: {code:java} 2024-11-15T15:32:33,436 WARN [qtp1989332276-50 {}] server.HttpChannel: /openapi java.lang.NoClassDefFoundError: javax/ws/rs/Path at io.swagger.v3.jaxrs2.Reader.read(Reader.java:285) ~[swagger-jaxrs2-2.2.25.jar:2.2.25] at io.swagger.v3.jaxrs2.Reader.read(Reader.java:199) ~[swagger-jaxrs2-2.2.25.jar:2.2.25] at io.swagger.v3.jaxrs2.Reader.read(Reader.java:228) ~[swagger-jaxrs2-2.2.25.jar:2.2.25] at io.swagger.v3.oas.integration.GenericOpenApiContext.read(GenericOpenApiContext.java:693) ~[swagger-integration-2.2.25.jar:2.2.25] at io.swagger.v3.jaxrs2.integration.OpenApiServlet.doGet(OpenApiServlet.java:55) ~[swagger-jaxrs2-2.2.25.jar:2.2.25] at javax.servlet.http.HttpServlet.service(HttpServlet.java:687) ~[javax.servlet-api-3.1.0.jar:3.1.0] at javax.servlet.http.HttpServlet.service(HttpServlet.java:790) ~[javax.servlet-api-3.1.0.jar:3.1.0] at org.apache.hbase.thirdparty.org.eclipse.jetty.servlet.ServletHolder.handle(ServletHolder.java:799) ~[hbase-shaded-jetty-4.1.9.jar:?] at org.apache.hbase.thirdparty.org.eclipse.jetty.servlet.ServletHandler$ChainEnd.doFilter(ServletHandler.java:1656) ~[hbase-shaded-jetty-4.1.9.jar:?] ... at org.apache.hbase.thirdparty.org.eclipse.jetty.util.thread.QueuedThreadPool$Runner.run(QueuedThreadPool.java:1034) ~[hbase-shaded-jetty-4.1.9.jar:?] at java.lang.Thread.run(Thread.java:840) ~[?:?] Caused by: java.lang.ClassNotFoundException: javax.ws.rs.Path at jdk.internal.loader.BuiltinClassLoader.loadClass(BuiltinClassLoader.java:641) ~[?:?] at jdk.internal.loader.ClassLoaders$AppClassLoader.loadClass(ClassLoaders.java:188) ~[?:?] at java.lang.ClassLoader.loadClass(ClassLoader.java:525) ~[?:?] ... 44 more {code} The OpenAPI / Swagger code directly depends on JAX-RS classes such as {{javax.ws.rs.Path}} but HBase REST uses shaded thirdparty version of these ({{{}org.apache.hbase.thirdparty.javax.ws.rs.Path{}}}). Even if we add the {{javax.ws.rs:javax.ws.rs-api}} library to the HBase REST project, the generated openapi JSON file will not contain, just the metadata (without any useful endpoints) because the OpenAPI / Swagger code only considers JAX-RS annotations. Also tried to add some Swagger annotations based on https://github.com/swagger-api/swagger-core/wiki/Swagger-2.X—Annotations but this did not help. Maybe we could make it work if we would add swagger-core to our [https://github.com/apache/hbase-thirdparty] repository and shade it as well. This I did not yet tried. h2. Build-time integration There is a Swagger Maven plugin which can be added to the build which builds the file: {{swagger-maven-plugin}} ({*}since 2.0.5{*}): provides a maven plugin to resolve an OpenAPI definition at build time (using {{{}swagger-jaxrs2{}}}). Please see [module readme|https://github.com/swagger-api/swagger-core/tree/master/modules/swagger-maven-plugin/README.md] However adding it requires also adding the {{javax.ws.rs:javax.ws.rs-api}} library to the HBase REST project otherwise the build will fail: {code:java} [ERROR] Failed to execute goal io.swagger.core.v3:swagger-maven-plugin:2.2.25:resolve (default-cli) on project hbase-rest: Execution default-cli of goal io.swagger.core.v3:swagger-maven-plugin:2.2.25:resolve failed: A required class was missing while executing io.swagger.core.v3:swagger-maven-plugin:2.2.25:resolve: javax/ws/rs/Path {code} If the JAX-RS library is added, then the build will be successful but the same problem: the generated openapi JSON file will not contain, just the metadata (without any useful endpoints) because the OpenAPI / Swagger code only considers JAX-RS annotations. Also tried to add some Swagger annotations based on https://github.com/swagger-api/swagger-core/wiki/Swagger-2.X—Annotations but this did not help. > Investigate integrating OpenAPI / Swagger to hbase-rest > ------------------------------------------------------- > > Key: HBASE-28977 > URL: https://issues.apache.org/jira/browse/HBASE-28977 > Project: HBase > Issue Type: Improvement > Components: REST > Reporter: Dávid Paksy > Assignee: Dávid Paksy > Priority: Major > > Using OpenAPI / Swagger it would be possible to generate a schema file of > HBase REST API. > In theory the generated schema file could be used as documentation / > generating API clients. > Even Swagger UI could be used to have an interactive playground for the HBase > REST API. > Check how much HBase could gain having this. -- This message was sent by Atlassian Jira (v8.20.10#820010)