1313import  java .io .File ;
1414import  java .io .IOException ;
1515import  java .net .HttpURLConnection ;
16+ import  java .net .URL ;
1617import  java .util .concurrent .CompletableFuture ;
1718import  java .util .concurrent .ExecutorService ;
1819import  java .util .concurrent .Executors ;
@@ -283,25 +284,19 @@ private static File createDeployment() throws IOException {
283284    }
284285
285286    private  ThreadPoolMetrics  getThreadPoolMetrics () {
286-         // Try different possible monitoring paths 
287-         String [] possiblePaths  = {
288-             "server.network.http-listener-1.thread-pool" ,
289-             "server.http-service.http-listener.http-listener-1.thread-pool" , 
290-             "server.applications.application.threadpool-test.thread-pool" ,
291-             "server.thread-pools.thread-pool.http-thread-pool" 
292-         };
293-         
287+         return  getThreadPoolMetrics ("http-listener-1" );
288+     }
289+     
290+     private  ThreadPoolMetrics  getThreadPoolMetrics (String  listenerName ) {
294291        // First, let's see what monitoring data is actually available 
295292        AsadminResult  listResult  = ASADMIN .exec ("list" , "*thread*" );
296293        System .out .println ("Available thread monitoring paths: "  + listResult .getStdOut ());
297294
298-         // Try to get metrics from the most likely path 
299-         AsadminResult  currentResult  = ASADMIN .exec ("get" , "-m" , 
300-             "server.network.http-listener-1.thread-pool.currentthreadcount" );
301-         AsadminResult  busyResult  = ASADMIN .exec ("get" , "-m" ,
302-             "server.network.http-listener-1.thread-pool.currentthreadsbusy" );
303-         AsadminResult  maxResult  = ASADMIN .exec ("get" , "-m" ,
304-             "server.network.http-listener-1.thread-pool.maxthreads" );
295+         // Try to get metrics from the specified listener 
296+         String  basePath  = "server.network."  + listenerName  + ".thread-pool" ;
297+         AsadminResult  currentResult  = ASADMIN .exec ("get" , "-m" , basePath  + ".currentthreadcount" );
298+         AsadminResult  busyResult  = ASADMIN .exec ("get" , "-m" , basePath  + ".currentthreadsbusy" );
299+         AsadminResult  maxResult  = ASADMIN .exec ("get" , "-m" , basePath  + ".maxthreads" );
305300
306301        return  new  ThreadPoolMetrics (
307302            extractValue (currentResult .getStdOut (), "currentthreadcount" ),
@@ -320,6 +315,20 @@ private int extractValue(String output, String metric) {
320315        return  0 ;
321316    }
322317
318+     private  void  makeRequest (String  urlString ) {
319+         try  {
320+             URL  url  = new  URL (urlString );
321+             HttpURLConnection  conn  = (HttpURLConnection ) url .openConnection ();
322+             conn .setRequestMethod ("GET" );
323+             conn .setConnectTimeout (5000 );
324+             conn .setReadTimeout (5000 );
325+             conn .getResponseCode ();
326+             conn .disconnect ();
327+         } catch  (Exception  e ) {
328+             // Ignore connection errors for load testing 
329+         }
330+     }
331+ 
323332    private  static  class  ThreadPoolMetrics  {
324333        final  int  currentThreadCount ;
325334        final  int  currentThreadsBusy ;
@@ -470,6 +479,116 @@ void testThreadPoolSizeCycling() throws Exception {
470479        }
471480    }
472481
482+     @ Test 
483+     void  testAdminListenerThreadPoolMetrics () throws  Exception  {
484+         // Get baseline metrics for admin-listener 
485+         ThreadPoolMetrics  adminBaseline  = getThreadPoolMetrics ("admin-listener" );
486+         
487+         // Verify admin listener has valid baseline metrics 
488+         assertTrue (adminBaseline .currentThreadCount  >= 0 , "Admin listener should have valid thread count" );
489+         assertTrue (adminBaseline .maxThreads  > 0 , "Admin listener should have positive max threads" );
490+         assertTrue (adminBaseline .currentThreadsBusy  >= 0 , "Admin listener should have valid busy count" );
491+         
492+         // Create load on admin port (4848) using asadmin commands 
493+         ExecutorService  executor  = Executors .newFixedThreadPool (3 );
494+         
495+         // Submit multiple concurrent admin requests 
496+         for  (int  i  = 0 ; i  < 5 ; i ++) {
497+             executor .submit (() -> {
498+                 try  {
499+                     ASADMIN .exec ("list" , "applications" );
500+                     Thread .sleep (100 );
501+                     ASADMIN .exec ("get" , "server.monitoring-service.*" );
502+                 } catch  (Exception  e ) {
503+                     // Ignore for load testing 
504+                 }
505+             });
506+         }
507+         
508+         Thread .sleep (500 ); // Let requests start 
509+         
510+         // Check metrics during admin load 
511+         ThreadPoolMetrics  adminUnderLoad  = getThreadPoolMetrics ("admin-listener" );
512+         
513+         // Admin listener should maintain valid metrics under load 
514+         assertTrue (adminUnderLoad .currentThreadCount  >= 0 , "Admin listener should maintain valid thread count under load" );
515+         assertTrue (adminUnderLoad .currentThreadsBusy  <= adminUnderLoad .currentThreadCount , 
516+             "Admin listener: Busy threads should not exceed current threads" );
517+         assertTrue (adminUnderLoad .maxThreads  > 0 , "Admin listener should maintain positive max threads" );
518+         
519+         executor .shutdown ();
520+         executor .awaitTermination (10 , TimeUnit .SECONDS );
521+         
522+         Thread .sleep (1000 ); // Let threads settle 
523+         
524+         // Final metrics check 
525+         ThreadPoolMetrics  adminFinal  = getThreadPoolMetrics ("admin-listener" );
526+         assertTrue (adminFinal .currentThreadCount  >= 0 , "Admin listener final thread count should be valid" );
527+         assertTrue (adminFinal .currentThreadsBusy  >= 0 , "Admin listener final busy count should be valid" );
528+     }
529+ 
530+     @ Test 
531+     void  testDualListenerThreadPoolMetrics () throws  Exception  {
532+         // First create http-listener-2 if it doesn't exist 
533+         AsadminResult  createResult  = ASADMIN .exec ("create-http-listener" , 
534+             "--listenerport=8081" , "--listeneraddress=0.0.0.0" , 
535+             "--defaultvs=server" , "http-listener-2" );
536+         
537+         try  {
538+             Thread .sleep (2000 ); // Allow listener to initialize 
539+             
540+             // Get baseline metrics for both listeners 
541+             ThreadPoolMetrics  listener1Baseline  = getThreadPoolMetrics ("http-listener-1" );
542+             ThreadPoolMetrics  listener2Baseline  = getThreadPoolMetrics ("http-listener-2" );
543+             
544+             // Verify both listeners have valid baseline metrics 
545+             assertTrue (listener1Baseline .currentThreadCount  >= 0 , "Listener 1 should have valid thread count" );
546+             assertTrue (listener2Baseline .currentThreadCount  >= 0 , "Listener 2 should have valid thread count" );
547+             
548+             // Create load on both listeners simultaneously 
549+             ExecutorService  executor  = Executors .newFixedThreadPool (10 );
550+             
551+             // Submit requests to both ports 
552+             for  (int  i  = 0 ; i  < 5 ; i ++) {
553+                 executor .submit (() -> makeRequest ("http://localhost:4848/"  + APP_NAME  + "/hello" ));
554+                 executor .submit (() -> makeRequest ("http://localhost:8081/"  + APP_NAME  + "/hello" ));
555+             }
556+             
557+             Thread .sleep (500 ); // Let requests start 
558+             
559+             // Check metrics during dual load 
560+             ThreadPoolMetrics  listener1UnderLoad  = getThreadPoolMetrics ("http-listener-1" );
561+             ThreadPoolMetrics  listener2UnderLoad  = getThreadPoolMetrics ("http-listener-2" );
562+             
563+             // Both listeners should show activity 
564+             assertTrue (listener1UnderLoad .currentThreadCount  >= 0 , "Listener 1 should maintain valid thread count under load" );
565+             assertTrue (listener2UnderLoad .currentThreadCount  >= 0 , "Listener 2 should maintain valid thread count under load" );
566+             
567+             // Thread counts should be consistent with busy counts 
568+             assertTrue (listener1UnderLoad .currentThreadsBusy  <= listener1UnderLoad .currentThreadCount , 
569+                 "Listener 1: Busy threads should not exceed current threads" );
570+             assertTrue (listener2UnderLoad .currentThreadsBusy  <= listener2UnderLoad .currentThreadCount ,
571+                 "Listener 2: Busy threads should not exceed current threads" );
572+             
573+             executor .shutdown ();
574+             executor .awaitTermination (10 , TimeUnit .SECONDS );
575+             
576+             Thread .sleep (1000 ); // Let threads settle 
577+             
578+             // Final metrics check 
579+             ThreadPoolMetrics  listener1Final  = getThreadPoolMetrics ("http-listener-1" );
580+             ThreadPoolMetrics  listener2Final  = getThreadPoolMetrics ("http-listener-2" );
581+             
582+             // Both should have valid final states 
583+             assertTrue (listener1Final .currentThreadCount  >= 0 , "Listener 1 final thread count should be valid" );
584+             assertTrue (listener2Final .currentThreadCount  >= 0 , "Listener 2 final thread count should be valid" );
585+             
586+         } finally  {
587+             // Clean up http-listener-2 
588+             ASADMIN .exec ("delete-http-listener" , "http-listener-2" );
589+         }
590+     }
591+ 
473592    @ Test 
474593    void  testThreadPoolSizeUnderLoad () throws  Exception  {
475594        ThreadPoolMetrics  initial  = getThreadPoolMetrics ();
0 commit comments