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


The following commit(s) were added to refs/heads/master by this push:
     new 161d0b1317 AXIS2-6099 add some unit tests and better Wildfly dep 
verification
161d0b1317 is described below

commit 161d0b131783717d5e35e66b51287c1002d9c6cc
Author: Robert Lazarski <[email protected]>
AuthorDate: Tue Dec 9 17:21:21 2025 -1000

    AXIS2-6099 add some unit tests and better Wildfly dep verification
---
 .../moshi/UndertowAxis2BufferIntegration.java      | 191 +++++++++++++++++----
 .../moshi/MemoryConstraintValidationTest.java      |  28 +--
 .../WildFlyAxis2CooperativeIntegrationTest.java    |  34 ++--
 3 files changed, 182 insertions(+), 71 deletions(-)

diff --git 
a/modules/transport-h2/src/main/java/org/apache/axis2/transport/h2/integration/moshi/UndertowAxis2BufferIntegration.java
 
b/modules/transport-h2/src/main/java/org/apache/axis2/transport/h2/integration/moshi/UndertowAxis2BufferIntegration.java
index 94b1fef796..36b3d58cdd 100644
--- 
a/modules/transport-h2/src/main/java/org/apache/axis2/transport/h2/integration/moshi/UndertowAxis2BufferIntegration.java
+++ 
b/modules/transport-h2/src/main/java/org/apache/axis2/transport/h2/integration/moshi/UndertowAxis2BufferIntegration.java
@@ -40,6 +40,7 @@ import 
org.apache.hc.client5.http.impl.nio.PoolingAsyncClientConnectionManager;
 import 
org.apache.hc.client5.http.impl.nio.PoolingAsyncClientConnectionManagerBuilder;
 import org.apache.hc.core5.http2.HttpVersionPolicy;
 import org.apache.hc.core5.http2.config.H2Config;
+import org.xnio.Pool;
 import org.xnio.XnioWorker;
 
 import com.squareup.moshi.JsonReader;
@@ -47,14 +48,6 @@ import com.squareup.moshi.JsonReader;
 import okio.BufferedSource;
 import okio.Okio;
 
-/**
- * Simple Pool interface for buffer management compatibility.
- */
-interface Pool<T> {
-    T allocate();
-    void free(T item);
-    int getAllocatedObjectCount();
-}
 
 /**
  * Moshi-specific Axis2 integration with Undertow shared buffer pools using 
Axis2 architecture patterns.
@@ -75,24 +68,161 @@ public class UndertowAxis2BufferIntegration {
     private static final Log log = 
LogFactory.getLog(UndertowAxis2BufferIntegration.class);
 
     /**
-     * Initialize Moshi-specific integration with Undertow servlet context.
-     *
-     * @param servletContext The servlet context providing access to 
Undertow's XNIO worker and buffer pool
+     * Cached WildFly integration singleton - initialized once, reused across 
all HTTP requests.
+     * This ensures zero performance overhead in high-volume enterprise 
applications.
+     */
+    private static volatile WildFlyResourceCache wildflyCache = null;
+    private static final Object initLock = new Object();
+
+    /**
+     * Cached WildFly resources discovered once during first servlet context 
access.
+     */
+    private static class WildFlyResourceCache {
+        final XnioWorker xnioWorker;
+        final Pool<ByteBuffer> sharedBufferPool;
+        final boolean integrationAvailable;
+        final String discoveryLog;
+
+        WildFlyResourceCache(ServletContext servletContext) {
+            StringBuilder discovery = new StringBuilder("WildFly resource 
discovery: ");
+            XnioWorker worker = null;
+            Pool<ByteBuffer> pool = null;
+
+            // Try multiple possible WildFly attribute names (test-compatible 
first)
+            String[] workerNames = {
+                "io.undertow.servlet.XnioWorker",   // Test compatibility - 
current expected name
+                "io.undertow.xnio.worker",          // Alternative WildFly name
+                "org.wildfly.undertow.worker",      // WildFly-specific name
+                "undertow.xnio.worker"              // Generic name
+            };
+
+            String[] poolNames = {
+                "io.undertow.servlet.BufferPool",   // Test compatibility - 
current expected name
+                "io.undertow.buffer-pool",          // Alternative WildFly name
+                "org.wildfly.undertow.buffer.pool", // WildFly-specific name
+                "undertow.buffer.pool"              // Generic name
+            };
+
+            // Search for XNIO Worker
+            for (String name : workerNames) {
+                Object attr = servletContext.getAttribute(name);
+                if (attr instanceof XnioWorker) {
+                    worker = (XnioWorker) attr;
+                    discovery.append("Found XnioWorker at 
'").append(name).append("', ");
+                    break;
+                }
+            }
+
+            // Search for Buffer Pool
+            for (String name : poolNames) {
+                Object attr = servletContext.getAttribute(name);
+                if (attr instanceof Pool) {
+                    try {
+                        @SuppressWarnings("unchecked")
+                        Pool<ByteBuffer> bufferPool = (Pool<ByteBuffer>) attr;
+                        pool = bufferPool;
+                        discovery.append("Found BufferPool at 
'").append(name).append("', ");
+                        break;
+                    } catch (ClassCastException e) {
+                        // Not a ByteBuffer pool, continue searching
+                    }
+                }
+            }
+
+            this.xnioWorker = worker;
+            this.sharedBufferPool = pool;
+            this.integrationAvailable = (worker != null && pool != null);
+            this.discoveryLog = discovery.toString();
+
+            // Log discovery results once
+            if (integrationAvailable) {
+                log.info("WildFly integration available: " + discoveryLog);
+            } else {
+                log.debug("WildFly integration not available: " + discoveryLog 
+
+                         "Worker=" + (worker != null) + ", Pool=" + (pool != 
null));
+
+                // Debug: enumerate all servlet context attributes to help 
discover correct names
+                if (log.isDebugEnabled()) {
+                    enumerateServletContextAttributes(servletContext);
+                }
+            }
+        }
+
+        /**
+         * Debug helper: enumerate all servlet context attributes to discover 
WildFly's actual attribute names.
+         * Only called when debug logging is enabled and integration fails.
+         */
+        private void enumerateServletContextAttributes(ServletContext 
servletContext) {
+            try {
+                java.util.Enumeration<String> attributeNames = 
servletContext.getAttributeNames();
+                StringBuilder allAttrs = new StringBuilder("All servlet 
context attributes: ");
+
+                while (attributeNames.hasMoreElements()) {
+                    String name = attributeNames.nextElement();
+                    Object value = servletContext.getAttribute(name);
+                    String className = (value != null) ? 
value.getClass().getSimpleName() : "null";
+                    
allAttrs.append(name).append("=").append(className).append(", ");
+                }
+
+                log.debug(allAttrs.toString());
+            } catch (Exception e) {
+                log.debug("Failed to enumerate servlet context attributes: " + 
e.getMessage());
+            }
+        }
+    }
+
+    /**
+     * Check if WildFly integration is available for this instance.
+     * @return true if both XNIO worker and buffer pool are available for this 
instance
+     */
+    public boolean isIntegrationAvailable() {
+        return xnioWorker != null && sharedBufferPool != null;
+    }
+
+    /**
+     * Get integration discovery information for monitoring/debugging.
+     * @return discovery log string, or null if not yet discovered
+     */
+    public static String getDiscoveryInfo() {
+        WildFlyResourceCache cache = wildflyCache;
+        return cache != null ? cache.discoveryLog : "Not yet initialized";
+    }
+
+    /**
+     * Clear the static cache - useful for testing environments.
+     * Package-private for use in test classes.
+     */
+    static void clearCache() {
+        wildflyCache = null;
+    }
+
+    /**
+     * Initialize Moshi-specific integration with cached WildFly resources.
+     * First call discovers and caches resources, subsequent calls reuse 
cached values.
+     * @param servletContext The servlet context (used only for first-time 
discovery)
      */
     public UndertowAxis2BufferIntegration(ServletContext servletContext) {
-        // Access Undertow's XNIO worker and buffer pool
-        this.xnioWorker = (XnioWorker) servletContext
-            .getAttribute("io.undertow.servlet.XnioWorker");
-        this.sharedBufferPool = (Pool<ByteBuffer>) servletContext
-            .getAttribute("io.undertow.servlet.BufferPool");
-
-        if (xnioWorker == null) {
-            log.warn("XNIO Worker not found in servlet context - Undertow 
integration may be limited");
+        // Lazy initialization with double-checked locking for thread safety
+        if (wildflyCache == null) {
+            synchronized (initLock) {
+                if (wildflyCache == null) {
+                    wildflyCache = new WildFlyResourceCache(servletContext);
+                }
+            }
         }
-        if (sharedBufferPool == null) {
-            log.warn("Shared buffer pool not found in servlet context - using 
default buffer management");
-        } else {
-            log.info("Successfully integrated Moshi-based Axis2 with Undertow 
shared buffer pool");
+
+        // Use cached resources (zero lookup overhead after first 
initialization)
+        this.xnioWorker = wildflyCache.xnioWorker;
+        this.sharedBufferPool = wildflyCache.sharedBufferPool;
+
+        // Emit warnings only if this is a fresh discovery attempt
+        if (!wildflyCache.integrationAvailable) {
+            if (xnioWorker == null) {
+                log.warn("XNIO Worker not found in servlet context - Undertow 
integration may be limited");
+            }
+            if (sharedBufferPool == null) {
+                log.warn("Shared buffer pool not found in servlet context - 
using default buffer management");
+            }
         }
     }
 
@@ -148,7 +278,7 @@ public class UndertowAxis2BufferIntegration {
             private int getSharedBufferSize() {
                 if (sharedBufferPool != null) {
                     // Align with Undertow's buffer configuration and Axis2's 
needs
-                    return sharedBufferPool.getAllocatedObjectCount() > 0 ? 
4096 : 2048;
+                    return 4096; // Use 4KB buffers when shared pool is 
available
                 } else {
                     // Fallback to default Axis2 buffer size optimized for 
Moshi
                     return 65536; // 64KB default for large JSON payloads
@@ -215,8 +345,7 @@ public class UndertowAxis2BufferIntegration {
             // Create BufferedSource with shared buffer pool awareness for 
Moshi optimization
             // Note: Okio uses its own buffer management, but we coordinate 
with shared pool metrics
             if (sharedBufferPool != null && log.isDebugEnabled()) {
-                log.debug("Creating Moshi-optimized BufferedSource with shared 
buffer pool awareness - " +
-                         "allocated buffers: " + 
sharedBufferPool.getAllocatedObjectCount());
+                log.debug("Creating Moshi-optimized BufferedSource with shared 
buffer pool awareness");
             }
             return Okio.buffer(Okio.source(inputStream));
         }
@@ -240,14 +369,6 @@ public class UndertowAxis2BufferIntegration {
         return sharedBufferPool;
     }
 
-    /**
-     * Check if Undertow integration is fully available.
-     *
-     * @return true if both XNIO worker and buffer pool are available
-     */
-    public boolean isIntegrationAvailable() {
-        return xnioWorker != null && sharedBufferPool != null;
-    }
 
     /**
      * Get integration status for monitoring and debugging.
@@ -261,7 +382,7 @@ public class UndertowAxis2BufferIntegration {
         if (isIntegrationAvailable()) {
             status.append("FULL - XNIO Worker and Buffer Pool available");
             if (sharedBufferPool != null) {
-                status.append(", Allocated Buffers: 
").append(sharedBufferPool.getAllocatedObjectCount());
+                status.append(", Buffer Pool: available");
             }
         } else if (xnioWorker != null) {
             status.append("PARTIAL - XNIO Worker available, Buffer Pool 
missing");
diff --git 
a/modules/transport-h2/src/test/java/org/apache/axis2/transport/h2/integration/moshi/MemoryConstraintValidationTest.java
 
b/modules/transport-h2/src/test/java/org/apache/axis2/transport/h2/integration/moshi/MemoryConstraintValidationTest.java
index 7772d7f794..93fbd8440a 100644
--- 
a/modules/transport-h2/src/test/java/org/apache/axis2/transport/h2/integration/moshi/MemoryConstraintValidationTest.java
+++ 
b/modules/transport-h2/src/test/java/org/apache/axis2/transport/h2/integration/moshi/MemoryConstraintValidationTest.java
@@ -45,6 +45,7 @@ import org.mockito.MockitoAnnotations;
 import io.undertow.server.HttpServerExchange;
 import io.undertow.util.HeaderMap;
 import io.undertow.util.Headers;
+import org.xnio.Pool;
 
 /**
  * Memory Constraint Validation Test Suite for WildFly 32 + Axis2 HTTP/2 
Integration.
@@ -84,6 +85,9 @@ public class MemoryConstraintValidationTest {
     public void setUp() throws Exception {
         MockitoAnnotations.openMocks(this);
 
+        // Clear static cache to ensure test isolation
+        UndertowAxis2BufferIntegration.clearCache();
+
         // Initialize memory coordination
         memoryCoordinator = new HTTP2MemoryCoordinator();
 
@@ -488,27 +492,11 @@ public class MemoryConstraintValidationTest {
 
     // Helper methods and classes
 
+    @SuppressWarnings("unchecked")
     private Pool<ByteBuffer> createMockBufferPoolWithTracking() {
-        return new Pool<ByteBuffer>() {
-            private int allocatedCount = 0;
-            private int maxAllocated = 10;
-
-            @Override
-            public ByteBuffer allocate() {
-                allocatedCount++;
-                return ByteBuffer.allocate(8192); // 8KB buffers
-            }
-
-            @Override
-            public void free(ByteBuffer item) {
-                allocatedCount = Math.max(0, allocatedCount - 1);
-            }
-
-            @Override
-            public int getAllocatedObjectCount() {
-                return Math.min(allocatedCount, maxAllocated);
-            }
-        };
+        Pool<ByteBuffer> pool = mock(Pool.class);
+        // Mock the pool - using Mockito to avoid XNIO interface complexity in 
tests
+        return pool;
     }
 
     private String generateMemoryTestPayload(long targetSizeBytes) {
diff --git 
a/modules/transport-h2/src/test/java/org/apache/axis2/transport/h2/integration/moshi/WildFlyAxis2CooperativeIntegrationTest.java
 
b/modules/transport-h2/src/test/java/org/apache/axis2/transport/h2/integration/moshi/WildFlyAxis2CooperativeIntegrationTest.java
index 92c458ec3d..0d5ace7342 100644
--- 
a/modules/transport-h2/src/test/java/org/apache/axis2/transport/h2/integration/moshi/WildFlyAxis2CooperativeIntegrationTest.java
+++ 
b/modules/transport-h2/src/test/java/org/apache/axis2/transport/h2/integration/moshi/WildFlyAxis2CooperativeIntegrationTest.java
@@ -40,6 +40,7 @@ import org.junit.Before;
 import org.junit.Test;
 import org.mockito.Mock;
 import org.mockito.MockitoAnnotations;
+import org.xnio.Pool;
 import org.xnio.XnioWorker;
 
 import io.undertow.server.HttpServerExchange;
@@ -80,6 +81,9 @@ public class WildFlyAxis2CooperativeIntegrationTest {
     public void setUp() throws Exception {
         MockitoAnnotations.openMocks(this);
 
+        // Clear static cache to ensure test isolation
+        UndertowAxis2BufferIntegration.clearCache();
+
         // Mock WildFly buffer pool (key integration point)
         mockBufferPool = createMockBufferPool();
 
@@ -310,10 +314,20 @@ public class WildFlyAxis2CooperativeIntegrationTest {
      */
     @Test
     public void testWildFlyIntegrationFallback() {
+        // Clear cache to ensure this test has clean state
+        UndertowAxis2BufferIntegration.clearCache();
+
         // Test integration without WildFly components
         ServletContext limitedContext = mock(ServletContext.class);
+        // Mock all possible attribute names to return null
         
when(limitedContext.getAttribute("io.undertow.servlet.XnioWorker")).thenReturn(null);
         
when(limitedContext.getAttribute("io.undertow.servlet.BufferPool")).thenReturn(null);
+        
when(limitedContext.getAttribute("io.undertow.xnio.worker")).thenReturn(null);
+        
when(limitedContext.getAttribute("io.undertow.buffer-pool")).thenReturn(null);
+        
when(limitedContext.getAttribute("org.wildfly.undertow.worker")).thenReturn(null);
+        
when(limitedContext.getAttribute("org.wildfly.undertow.buffer.pool")).thenReturn(null);
+        
when(limitedContext.getAttribute("undertow.xnio.worker")).thenReturn(null);
+        
when(limitedContext.getAttribute("undertow.buffer.pool")).thenReturn(null);
 
         UndertowAxis2BufferIntegration limitedIntegration = new 
UndertowAxis2BufferIntegration(limitedContext);
 
@@ -331,23 +345,11 @@ public class WildFlyAxis2CooperativeIntegrationTest {
 
     // Helper methods
 
+    @SuppressWarnings("unchecked")
     private Pool<ByteBuffer> createMockBufferPool() {
-        return new Pool<ByteBuffer>() {
-            @Override
-            public ByteBuffer allocate() {
-                return ByteBuffer.allocate(8192); // 8KB buffer
-            }
-
-            @Override
-            public void free(ByteBuffer item) {
-                // Mock implementation
-            }
-
-            @Override
-            public int getAllocatedObjectCount() {
-                return 10; // Mock active buffers
-            }
-        };
+        Pool<ByteBuffer> pool = mock(Pool.class);
+        // Mock the pool - using Mockito to avoid XNIO interface complexity in 
tests
+        return pool;
     }
 
     private String generateLargeJsonPayload(int sizeBytes) {

Reply via email to