This is an automated email from the ASF dual-hosted git repository.

robertlazarski pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/axis-axis2-java-core.git

commit 9fee3fca613f994c4b70691931d31c0acd1a4276
Author: Robert Lazarski <[email protected]>
AuthorDate: Sat Apr 4 15:23:11 2026 -1000

    Wire axis2-openapi module into springbootdemo samples
    
    Adds the missing HTTP routing layer so the OpenAPI endpoints are reachable
    in both the Tomcat 11 and WildFly springbootdemo deployments.
    
    Changes per sample:
    - pom.xml: add axis2-openapi dependency
    - axis2.xml: add <module ref="openapi"/>
    - OpenApiController: new Spring @Controller routing GET /openapi.json,
      /openapi.yaml, /swagger-ui to SwaggerUIHandler; retrieves
      ConfigurationContext from ServletContext via 
AxisServlet.CONFIGURATION_CONTEXT
    - Axis2Application: add @Order(2) OpenAPI filter chain that allows
      unauthenticated GET requests to the three OpenAPI paths, bypassing
      the HTTPPostOnlyRejectionFilter and JWT auth that protects /services/*;
      bump login chain from @Order(1) to @Order(3) accordingly
    
    Co-Authored-By: Claude Sonnet 4.6 <[email protected]>
---
 .../src/userguide/springbootdemo-tomcat11/pom.xml  |  5 ++
 .../resources-axis2/conf/axis2.xml                 |  3 +
 .../userguide/springboot/Axis2Application.java     | 27 +++++-
 .../configuration/OpenApiController.java           | 99 ++++++++++++++++++++++
 .../userguide/src/userguide/springbootdemo/pom.xml |  5 ++
 .../springbootdemo/resources-axis2/conf/axis2.xml  |  3 +
 .../userguide/springboot/Axis2Application.java     | 27 +++++-
 .../configuration/OpenApiController.java           | 99 ++++++++++++++++++++++
 8 files changed, 264 insertions(+), 4 deletions(-)

diff --git 
a/modules/samples/userguide/src/userguide/springbootdemo-tomcat11/pom.xml 
b/modules/samples/userguide/src/userguide/springbootdemo-tomcat11/pom.xml
index 8cc7a00112..c1de1b099e 100644
--- a/modules/samples/userguide/src/userguide/springbootdemo-tomcat11/pom.xml
+++ b/modules/samples/userguide/src/userguide/springbootdemo-tomcat11/pom.xml
@@ -230,6 +230,11 @@
             <artifactId>axis2-jaxws</artifactId>
            <version>2.0.1-SNAPSHOT</version>
         </dependency>
+        <dependency>
+            <groupId>org.apache.axis2</groupId>
+            <artifactId>axis2-openapi</artifactId>
+           <version>2.0.1-SNAPSHOT</version>
+        </dependency>
         <dependency>
             <groupId>org.apache.neethi</groupId>
             <artifactId>neethi</artifactId>
diff --git 
a/modules/samples/userguide/src/userguide/springbootdemo-tomcat11/resources-axis2/conf/axis2.xml
 
b/modules/samples/userguide/src/userguide/springbootdemo-tomcat11/resources-axis2/conf/axis2.xml
index 5ab7e1e1ca..b0f955b614 100644
--- 
a/modules/samples/userguide/src/userguide/springbootdemo-tomcat11/resources-axis2/conf/axis2.xml
+++ 
b/modules/samples/userguide/src/userguide/springbootdemo-tomcat11/resources-axis2/conf/axis2.xml
@@ -258,6 +258,9 @@
     <!-- commented out for the Axis2 spring boot demo that uses JSON -->
     <!-- <module ref="addressing"/> -->
 
+    <!-- OpenAPI/Swagger documentation module -->
+    <module ref="openapi"/>
+
     <!--Configuring module , providing parameters for modules whether they 
refer or not-->
     <!--<moduleConfig name="addressing">-->
     <!--<parameter name="addressingPara">N/A</parameter>-->
diff --git 
a/modules/samples/userguide/src/userguide/springbootdemo-tomcat11/src/main/java/userguide/springboot/Axis2Application.java
 
b/modules/samples/userguide/src/userguide/springbootdemo-tomcat11/src/main/java/userguide/springboot/Axis2Application.java
index 471f9b8c18..838d1bf3b6 100644
--- 
a/modules/samples/userguide/src/userguide/springbootdemo-tomcat11/src/main/java/userguide/springboot/Axis2Application.java
+++ 
b/modules/samples/userguide/src/userguide/springbootdemo-tomcat11/src/main/java/userguide/springboot/Axis2Application.java
@@ -347,11 +347,34 @@ public class Axis2Application extends 
SpringBootServletInitializer {
             return headerFilter;
         }
       
-        // these two chains are a binary choice. 
+        // OpenAPI documentation endpoints — GET requests, no auth required
+        class OpenApiRequestMatcher implements RequestMatcher {
+            private static final String[] OPENAPI_PATHS = {"/openapi.json", 
"/openapi.yaml", "/swagger-ui"};
+
+            @Override
+            public boolean matches(HttpServletRequest request) {
+                String uri = request.getRequestURI();
+                for (String path : OPENAPI_PATHS) {
+                    if (uri.equals(path) || uri.startsWith(path + "/")) {
+                        return true;
+                    }
+                }
+                return false;
+            }
+        }
+
+        @Bean(name = "springSecurityFilterChainOpenApi")
+        @Order(2)
+        public SecurityFilterChain springSecurityFilterChainOpenApi() throws 
Exception {
+            // Only header filter — no POST restriction, no JWT, no login 
processing
+            return new DefaultSecurityFilterChain(new OpenApiRequestMatcher(), 
headerWriterFilter());
+        }
+
+        // these two chains are a binary choice.
         // A login url will match, otherwise invoke jwtAuthenticationFilter
 
         @Bean(name = "springSecurityFilterChainLogin")
-       @Order(1)
+       @Order(3)
         public SecurityFilterChain springSecurityFilterChainLogin() throws 
ServletException, Exception {
             String logPrefix = 
"GenericAccessDecisionManager.springSecurityFilterChain , ";
             logger.debug(logPrefix + "inside main filter config ...");
diff --git 
a/modules/samples/userguide/src/userguide/springbootdemo-tomcat11/src/main/java/userguide/springboot/configuration/OpenApiController.java
 
b/modules/samples/userguide/src/userguide/springbootdemo-tomcat11/src/main/java/userguide/springboot/configuration/OpenApiController.java
new file mode 100644
index 0000000000..1518b36c5c
--- /dev/null
+++ 
b/modules/samples/userguide/src/userguide/springbootdemo-tomcat11/src/main/java/userguide/springboot/configuration/OpenApiController.java
@@ -0,0 +1,99 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package userguide.springboot.configuration;
+
+import jakarta.servlet.ServletContext;
+import jakarta.servlet.http.HttpServletRequest;
+import jakarta.servlet.http.HttpServletResponse;
+import org.apache.axis2.context.ConfigurationContext;
+import org.apache.axis2.openapi.OpenApiModule;
+import org.apache.axis2.openapi.SwaggerUIHandler;
+import org.apache.axis2.transport.http.AxisServlet;
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Controller;
+import org.springframework.web.bind.annotation.GetMapping;
+
+/**
+ * Routes OpenAPI documentation requests to the Axis2 OpenAPI module handlers.
+ *
+ * The axis2-openapi module stores its handlers in ConfigurationContext during
+ * module init. AxisServlet stores ConfigurationContext in ServletContext under
+ * the key AxisServlet.CONFIGURATION_CONTEXT ("CONFIGURATION_CONTEXT"). This
+ * controller bridges Spring MVC routing to those handlers, enabling the 
standard
+ * OpenAPI endpoints alongside the Axis2 /services/* path.
+ *
+ * Endpoints served:
+ *   GET /openapi.json  - OpenAPI 3.0.1 specification (JSON)
+ *   GET /openapi.yaml  - OpenAPI 3.0.1 specification (YAML)
+ *   GET /swagger-ui    - Interactive Swagger UI documentation page
+ */
+@Controller
+public class OpenApiController {
+
+    private static final Log log = LogFactory.getLog(OpenApiController.class);
+
+    @Autowired
+    private ServletContext servletContext;
+
+    private SwaggerUIHandler getHandler() {
+        ConfigurationContext configContext = (ConfigurationContext)
+                servletContext.getAttribute(AxisServlet.CONFIGURATION_CONTEXT);
+        if (configContext == null) {
+            log.warn("AxisServlet ConfigurationContext not found in 
ServletContext — AxisServlet may not have started yet");
+            return null;
+        }
+        SwaggerUIHandler handler = 
OpenApiModule.getSwaggerUIHandler(configContext);
+        if (handler == null) {
+            log.warn("OpenAPI module not initialized — ensure axis2-openapi is 
on the classpath and <module ref=\"openapi\"/> is in axis2.xml");
+        }
+        return handler;
+    }
+
+    @GetMapping("/openapi.json")
+    public void openApiJson(HttpServletRequest request, HttpServletResponse 
response) throws Exception {
+        SwaggerUIHandler handler = getHandler();
+        if (handler == null) {
+            response.sendError(HttpServletResponse.SC_SERVICE_UNAVAILABLE, 
"OpenAPI module not available");
+            return;
+        }
+        handler.handleOpenApiJsonRequest(request, response);
+    }
+
+    @GetMapping("/openapi.yaml")
+    public void openApiYaml(HttpServletRequest request, HttpServletResponse 
response) throws Exception {
+        SwaggerUIHandler handler = getHandler();
+        if (handler == null) {
+            response.sendError(HttpServletResponse.SC_SERVICE_UNAVAILABLE, 
"OpenAPI module not available");
+            return;
+        }
+        handler.handleOpenApiYamlRequest(request, response);
+    }
+
+    @GetMapping("/swagger-ui")
+    public void swaggerUi(HttpServletRequest request, HttpServletResponse 
response) throws Exception {
+        SwaggerUIHandler handler = getHandler();
+        if (handler == null) {
+            response.sendError(HttpServletResponse.SC_SERVICE_UNAVAILABLE, 
"OpenAPI module not available");
+            return;
+        }
+        handler.handleSwaggerUIRequest(request, response);
+    }
+}
diff --git a/modules/samples/userguide/src/userguide/springbootdemo/pom.xml 
b/modules/samples/userguide/src/userguide/springbootdemo/pom.xml
index 8cc7a00112..c1de1b099e 100644
--- a/modules/samples/userguide/src/userguide/springbootdemo/pom.xml
+++ b/modules/samples/userguide/src/userguide/springbootdemo/pom.xml
@@ -230,6 +230,11 @@
             <artifactId>axis2-jaxws</artifactId>
            <version>2.0.1-SNAPSHOT</version>
         </dependency>
+        <dependency>
+            <groupId>org.apache.axis2</groupId>
+            <artifactId>axis2-openapi</artifactId>
+           <version>2.0.1-SNAPSHOT</version>
+        </dependency>
         <dependency>
             <groupId>org.apache.neethi</groupId>
             <artifactId>neethi</artifactId>
diff --git 
a/modules/samples/userguide/src/userguide/springbootdemo/resources-axis2/conf/axis2.xml
 
b/modules/samples/userguide/src/userguide/springbootdemo/resources-axis2/conf/axis2.xml
index 5ab7e1e1ca..b0f955b614 100644
--- 
a/modules/samples/userguide/src/userguide/springbootdemo/resources-axis2/conf/axis2.xml
+++ 
b/modules/samples/userguide/src/userguide/springbootdemo/resources-axis2/conf/axis2.xml
@@ -258,6 +258,9 @@
     <!-- commented out for the Axis2 spring boot demo that uses JSON -->
     <!-- <module ref="addressing"/> -->
 
+    <!-- OpenAPI/Swagger documentation module -->
+    <module ref="openapi"/>
+
     <!--Configuring module , providing parameters for modules whether they 
refer or not-->
     <!--<moduleConfig name="addressing">-->
     <!--<parameter name="addressingPara">N/A</parameter>-->
diff --git 
a/modules/samples/userguide/src/userguide/springbootdemo/src/main/java/userguide/springboot/Axis2Application.java
 
b/modules/samples/userguide/src/userguide/springbootdemo/src/main/java/userguide/springboot/Axis2Application.java
index 73cb30c642..c6e442891c 100644
--- 
a/modules/samples/userguide/src/userguide/springbootdemo/src/main/java/userguide/springboot/Axis2Application.java
+++ 
b/modules/samples/userguide/src/userguide/springbootdemo/src/main/java/userguide/springboot/Axis2Application.java
@@ -341,11 +341,34 @@ public class Axis2Application extends 
SpringBootServletInitializer {
             return headerFilter;
         }
       
-        // these two chains are a binary choice. 
+        // OpenAPI documentation endpoints — GET requests, no auth required
+        class OpenApiRequestMatcher implements RequestMatcher {
+            private static final String[] OPENAPI_PATHS = {"/openapi.json", 
"/openapi.yaml", "/swagger-ui"};
+
+            @Override
+            public boolean matches(HttpServletRequest request) {
+                String uri = request.getRequestURI();
+                for (String path : OPENAPI_PATHS) {
+                    if (uri.equals(path) || uri.startsWith(path + "/")) {
+                        return true;
+                    }
+                }
+                return false;
+            }
+        }
+
+        @Bean(name = "springSecurityFilterChainOpenApi")
+        @Order(2)
+        public SecurityFilterChain springSecurityFilterChainOpenApi() throws 
Exception {
+            // Only header filter — no POST restriction, no JWT, no login 
processing
+            return new DefaultSecurityFilterChain(new OpenApiRequestMatcher(), 
headerWriterFilter());
+        }
+
+        // these two chains are a binary choice.
         // A login url will match, otherwise invoke jwtAuthenticationFilter
 
         @Bean(name = "springSecurityFilterChainLogin")
-       @Order(1)
+       @Order(3)
         public SecurityFilterChain springSecurityFilterChainLogin() throws 
ServletException, Exception {
             String logPrefix = 
"GenericAccessDecisionManager.springSecurityFilterChain , ";
             logger.debug(logPrefix + "inside main filter config ...");
diff --git 
a/modules/samples/userguide/src/userguide/springbootdemo/src/main/java/userguide/springboot/configuration/OpenApiController.java
 
b/modules/samples/userguide/src/userguide/springbootdemo/src/main/java/userguide/springboot/configuration/OpenApiController.java
new file mode 100644
index 0000000000..1518b36c5c
--- /dev/null
+++ 
b/modules/samples/userguide/src/userguide/springbootdemo/src/main/java/userguide/springboot/configuration/OpenApiController.java
@@ -0,0 +1,99 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package userguide.springboot.configuration;
+
+import jakarta.servlet.ServletContext;
+import jakarta.servlet.http.HttpServletRequest;
+import jakarta.servlet.http.HttpServletResponse;
+import org.apache.axis2.context.ConfigurationContext;
+import org.apache.axis2.openapi.OpenApiModule;
+import org.apache.axis2.openapi.SwaggerUIHandler;
+import org.apache.axis2.transport.http.AxisServlet;
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Controller;
+import org.springframework.web.bind.annotation.GetMapping;
+
+/**
+ * Routes OpenAPI documentation requests to the Axis2 OpenAPI module handlers.
+ *
+ * The axis2-openapi module stores its handlers in ConfigurationContext during
+ * module init. AxisServlet stores ConfigurationContext in ServletContext under
+ * the key AxisServlet.CONFIGURATION_CONTEXT ("CONFIGURATION_CONTEXT"). This
+ * controller bridges Spring MVC routing to those handlers, enabling the 
standard
+ * OpenAPI endpoints alongside the Axis2 /services/* path.
+ *
+ * Endpoints served:
+ *   GET /openapi.json  - OpenAPI 3.0.1 specification (JSON)
+ *   GET /openapi.yaml  - OpenAPI 3.0.1 specification (YAML)
+ *   GET /swagger-ui    - Interactive Swagger UI documentation page
+ */
+@Controller
+public class OpenApiController {
+
+    private static final Log log = LogFactory.getLog(OpenApiController.class);
+
+    @Autowired
+    private ServletContext servletContext;
+
+    private SwaggerUIHandler getHandler() {
+        ConfigurationContext configContext = (ConfigurationContext)
+                servletContext.getAttribute(AxisServlet.CONFIGURATION_CONTEXT);
+        if (configContext == null) {
+            log.warn("AxisServlet ConfigurationContext not found in 
ServletContext — AxisServlet may not have started yet");
+            return null;
+        }
+        SwaggerUIHandler handler = 
OpenApiModule.getSwaggerUIHandler(configContext);
+        if (handler == null) {
+            log.warn("OpenAPI module not initialized — ensure axis2-openapi is 
on the classpath and <module ref=\"openapi\"/> is in axis2.xml");
+        }
+        return handler;
+    }
+
+    @GetMapping("/openapi.json")
+    public void openApiJson(HttpServletRequest request, HttpServletResponse 
response) throws Exception {
+        SwaggerUIHandler handler = getHandler();
+        if (handler == null) {
+            response.sendError(HttpServletResponse.SC_SERVICE_UNAVAILABLE, 
"OpenAPI module not available");
+            return;
+        }
+        handler.handleOpenApiJsonRequest(request, response);
+    }
+
+    @GetMapping("/openapi.yaml")
+    public void openApiYaml(HttpServletRequest request, HttpServletResponse 
response) throws Exception {
+        SwaggerUIHandler handler = getHandler();
+        if (handler == null) {
+            response.sendError(HttpServletResponse.SC_SERVICE_UNAVAILABLE, 
"OpenAPI module not available");
+            return;
+        }
+        handler.handleOpenApiYamlRequest(request, response);
+    }
+
+    @GetMapping("/swagger-ui")
+    public void swaggerUi(HttpServletRequest request, HttpServletResponse 
response) throws Exception {
+        SwaggerUIHandler handler = getHandler();
+        if (handler == null) {
+            response.sendError(HttpServletResponse.SC_SERVICE_UNAVAILABLE, 
"OpenAPI module not available");
+            return;
+        }
+        handler.handleSwaggerUIRequest(request, response);
+    }
+}

Reply via email to