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

dsmiley pushed a commit to branch branch_9x
in repository https://gitbox.apache.org/repos/asf/solr.git


The following commit(s) were added to refs/heads/branch_9x by this push:
     new df55fe9  SOLR-15124: remove /core/admin/[threads|properties|logging] 
APIs (#198)
df55fe9 is described below

commit df55fe90d4c4133a7045bdd89bbcbbb84e6e617a
Author: Nazerke Seidan <[email protected]>
AuthorDate: Mon Jan 24 23:54:48 2022 -0500

    SOLR-15124: remove /core/admin/[threads|properties|logging] APIs (#198)
    
    Removed three *core* level admin API endpoints because they are ALREADY 
registered at the node level where they
      really belong: /admin/threads, /admin/properties, /admin/logging
    
    Co-authored-by: Nazerke Seidan <[email protected]>
    Co-authored-by: David Smiley <[email protected]>
---
 solr/CHANGES.txt                                   |  3 +
 .../apache/solr/handler/admin/LoggingHandler.java  | 33 +++-----
 solr/core/src/resources/ImplicitPlugins.json       | 12 ---
 .../test/org/apache/solr/core/SolrCoreTest.java    |  3 -
 .../apache/solr/core/TestSolrConfigHandler.java    |  3 -
 .../solr/handler/admin/LoggingHandlerTest.java     | 69 ++++++++++-----
 .../admin/PropertiesRequestHandlerTest.java        | 20 ++---
 .../solr/handler/admin/ThreadDumpHandlerTest.java  | 98 ++++++++++++++--------
 .../src/major-changes-in-solr-9.adoc               |  3 +
 9 files changed, 140 insertions(+), 104 deletions(-)

diff --git a/solr/CHANGES.txt b/solr/CHANGES.txt
index 84a6b32..ed1caa7 100644
--- a/solr/CHANGES.txt
+++ b/solr/CHANGES.txt
@@ -487,6 +487,9 @@ Other Changes
 * SOLR-14858: Add the server WEB-INF/lib directory to the classpath for the 
solr-exporter script. Will allow the script
   to work when the dist/solrj-lib jars are missing in the Docker image. 
(Houston Putman)
 
+* SOLR-15124: Removed three core level admin API endpoints because they are 
already registered at the node level where they
+  really belong: /admin/threads, /admin/properties, /admin/logging (Nazerke 
Seidan, David Smiley)
+
 * SOLR-14142: Jetty's RequestLog is enabled by default. If you don't want 
these logs, you can disable
   via SOLR_REQUESTLOG_ENABLED=false.  (rmuir, janhoy)
 
diff --git 
a/solr/core/src/java/org/apache/solr/handler/admin/LoggingHandler.java 
b/solr/core/src/java/org/apache/solr/handler/admin/LoggingHandler.java
index 380db40..9656051 100644
--- a/solr/core/src/java/org/apache/solr/handler/admin/LoggingHandler.java
+++ b/solr/core/src/java/org/apache/solr/handler/admin/LoggingHandler.java
@@ -16,6 +16,13 @@
  */
 package org.apache.solr.handler.admin;
 
+import java.lang.invoke.MethodHandles;
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.Collections;
+import java.util.List;
+import java.util.concurrent.atomic.AtomicBoolean;
+
 import org.apache.solr.api.AnnotatedApi;
 import org.apache.solr.api.Api;
 import org.apache.solr.common.SolrDocumentList;
@@ -24,7 +31,6 @@ import org.apache.solr.common.SolrException.ErrorCode;
 import org.apache.solr.common.params.SolrParams;
 import org.apache.solr.common.util.SimpleOrderedMap;
 import org.apache.solr.core.CoreContainer;
-import org.apache.solr.core.SolrCore;
 import org.apache.solr.handler.RequestHandlerBase;
 import org.apache.solr.handler.admin.api.NodeLoggingAPI;
 import org.apache.solr.logging.LogWatcher;
@@ -32,44 +38,25 @@ import org.apache.solr.logging.LoggerInfo;
 import org.apache.solr.request.SolrQueryRequest;
 import org.apache.solr.response.SolrQueryResponse;
 import org.apache.solr.security.AuthorizationContext;
-import org.apache.solr.util.plugin.SolrCoreAware;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
-import java.lang.invoke.MethodHandles;
-import java.util.ArrayList;
-import java.util.Collection;
-import java.util.Collections;
-import java.util.List;
-import java.util.concurrent.atomic.AtomicBoolean;
-
 
 /**
  * A request handler to show which loggers are registered and allows you to 
set them
  *
  * @since 4.0
  */
-public class LoggingHandler extends RequestHandlerBase implements 
SolrCoreAware {
+public class LoggingHandler extends RequestHandlerBase {
   private static final Logger log = 
LoggerFactory.getLogger(MethodHandles.lookup().lookupClass());
 
-  private LogWatcher<?> watcher;
+  private final LogWatcher<?> watcher;
   private final CoreContainer cc;
   
   public LoggingHandler(CoreContainer cc) {
     this.cc = cc;
     this.watcher = cc.getLogging();
   }
-  
-  public LoggingHandler() {
-    this.cc = null;
-  }
-  
-  @Override
-  public void inform(SolrCore core) {
-    if (watcher == null) {
-      watcher = core.getCoreContainer().getLogging();
-    }
-  }
 
   @Override
   public void handleRequestBody(SolrQueryRequest req, SolrQueryResponse rsp) 
throws Exception {
@@ -145,7 +132,7 @@ public class LoggingHandler extends RequestHandlerBase 
implements SolrCoreAware
     }
     else {
       rsp.add("levels", watcher.getAllLevels());
-  
+
       List<LoggerInfo> loggers = new ArrayList<>(watcher.getAllLoggers());
       Collections.sort(loggers);
   
diff --git a/solr/core/src/resources/ImplicitPlugins.json 
b/solr/core/src/resources/ImplicitPlugins.json
index f9f9be57..14b51cb 100644
--- a/solr/core/src/resources/ImplicitPlugins.json
+++ b/solr/core/src/resources/ImplicitPlugins.json
@@ -77,18 +77,6 @@
     "/admin/plugins": {
       "class": "solr.PluginInfoHandler"
     },
-    "/admin/threads": {
-      "class": "solr.ThreadDumpHandler",
-      "useParams":"_ADMIN_THREADS"
-    },
-    "/admin/properties": {
-      "class": "solr.PropertiesRequestHandler",
-      "useParams":"_ADMIN_PROPERTIES"
-    },
-    "/admin/logging": {
-      "class": "solr.LoggingHandler",
-      "useParams":"_ADMIN_LOGGING"
-    },
     "/admin/file": {
       "class": "solr.ShowFileRequestHandler",
       "useParams":"_ADMIN_FILE"
diff --git a/solr/core/src/test/org/apache/solr/core/SolrCoreTest.java 
b/solr/core/src/test/org/apache/solr/core/SolrCoreTest.java
index a10cc85..2b1db3d 100644
--- a/solr/core/src/test/org/apache/solr/core/SolrCoreTest.java
+++ b/solr/core/src/test/org/apache/solr/core/SolrCoreTest.java
@@ -89,15 +89,12 @@ public class SolrCoreTest extends SolrTestCaseJ4 {
     int ihCount = 0;
     {
       ++ihCount; assertEquals(pathToClassMap.get("/admin/file"), 
"solr.ShowFileRequestHandler");
-      ++ihCount; assertEquals(pathToClassMap.get("/admin/logging"), 
"solr.LoggingHandler");
       ++ihCount; assertEquals(pathToClassMap.get("/admin/luke"), 
"solr.LukeRequestHandler");
       ++ihCount; assertEquals(pathToClassMap.get("/admin/mbeans"), 
"solr.SolrInfoMBeanHandler");
       ++ihCount; assertEquals(pathToClassMap.get("/admin/ping"), 
"solr.PingRequestHandler");
       ++ihCount; assertEquals(pathToClassMap.get("/admin/plugins"), 
"solr.PluginInfoHandler");
-      ++ihCount; assertEquals(pathToClassMap.get("/admin/properties"), 
"solr.PropertiesRequestHandler");
       ++ihCount; assertEquals(pathToClassMap.get("/admin/segments"), 
"solr.SegmentsInfoRequestHandler");
       ++ihCount; assertEquals(pathToClassMap.get("/admin/system"), 
"solr.SystemInfoHandler");
-      ++ihCount; assertEquals(pathToClassMap.get("/admin/threads"), 
"solr.ThreadDumpHandler");
       ++ihCount; assertEquals(pathToClassMap.get("/config"), 
"solr.SolrConfigHandler");
       ++ihCount; assertEquals(pathToClassMap.get("/export"), 
"solr.ExportHandler");
       ++ihCount; assertEquals(pathToClassMap.get("/terms"), 
"solr.SearchHandler");
diff --git a/solr/core/src/test/org/apache/solr/core/TestSolrConfigHandler.java 
b/solr/core/src/test/org/apache/solr/core/TestSolrConfigHandler.java
index e760c20..b7e833e 100644
--- a/solr/core/src/test/org/apache/solr/core/TestSolrConfigHandler.java
+++ b/solr/core/src/test/org/apache/solr/core/TestSolrConfigHandler.java
@@ -156,9 +156,6 @@ public class TestSolrConfigHandler extends RestTestBase {
     assertNotNull(confMap._get(asList("config", "requestHandler", 
"/admin/system"), null));
     assertNotNull(confMap._get(asList("config", "requestHandler", 
"/admin/mbeans"), null));
     assertNotNull(confMap._get(asList("config", "requestHandler", 
"/admin/plugins"), null));
-    assertNotNull(confMap._get(asList("config", "requestHandler", 
"/admin/threads"), null));
-    assertNotNull(confMap._get(asList("config", "requestHandler", 
"/admin/properties"), null));
-    assertNotNull(confMap._get(asList("config", "requestHandler", 
"/admin/logging"), null));
     assertNotNull(confMap._get(asList("config", "requestHandler", 
"/admin/file"), null));
     assertNotNull(confMap._get(asList("config", "requestHandler", 
"/admin/ping"), null));
 
diff --git 
a/solr/core/src/test/org/apache/solr/handler/admin/LoggingHandlerTest.java 
b/solr/core/src/test/org/apache/solr/handler/admin/LoggingHandlerTest.java
index d98c65b..8f7e4b8 100644
--- a/solr/core/src/test/org/apache/solr/handler/admin/LoggingHandlerTest.java
+++ b/solr/core/src/test/org/apache/solr/handler/admin/LoggingHandlerTest.java
@@ -17,12 +17,19 @@
 package org.apache.solr.handler.admin;
 
 
+import java.util.ArrayList;
+
 import org.apache.logging.log4j.Level;
 import org.apache.logging.log4j.LogManager;
 import org.apache.logging.log4j.core.LoggerContext;
 import org.apache.logging.log4j.core.config.Configuration;
 import org.apache.solr.SolrTestCaseJ4;
-import org.apache.solr.common.params.CommonParams;
+import org.apache.solr.client.solrj.SolrClient;
+import org.apache.solr.client.solrj.SolrRequest;
+import org.apache.solr.client.solrj.embedded.EmbeddedSolrServer;
+import org.apache.solr.client.solrj.request.GenericSolrRequest;
+import org.apache.solr.common.params.ModifiableSolrParams;
+import org.apache.solr.common.util.NamedList;
 import org.apache.solr.common.util.SuppressForbidden;
 import org.apache.solr.util.LogLevel;
 import org.junit.BeforeClass;
@@ -66,30 +73,54 @@ public class LoggingHandlerTest extends SolrTestCaseJ4 {
                  config.getLoggerConfig(PARENT_LOGGER_NAME));
     assertEquals(Level.DEBUG, 
config.getLoggerConfig(CLASS_LOGGER_NAME).getLevel());
 
-    assertQ("Show Log Levels OK",
-            req(CommonParams.QT,"/admin/logging")
-            
,"//arr[@name='loggers']/lst/str[.='"+CLASS_LOGGER_NAME+"']/../str[@name='level'][.='DEBUG']"
-            
,"//arr[@name='loggers']/lst/str[.='"+PARENT_LOGGER_NAME+"']/../null[@name='level']"
-            );
-
-    assertQ("Set a (new) level",
-            req(CommonParams.QT,"/admin/logging",  
-                "set", PARENT_LOGGER_NAME+":TRACE")
-            
,"//arr[@name='loggers']/lst/str[.='"+PARENT_LOGGER_NAME+"']/../str[@name='level'][.='TRACE']"
-            );
+    SolrClient client = new EmbeddedSolrServer(h.getCore());
+    ModifiableSolrParams mparams = new ModifiableSolrParams();
+
+    NamedList<Object> rsp = client.request(new 
GenericSolrRequest(SolrRequest.METHOD.GET, "/admin/info/logging", mparams));
+
+    @SuppressWarnings({"unchecked"})
+    ArrayList<NamedList<Object>> loggers = (ArrayList<NamedList<Object>>) 
rsp._get("loggers", null);
+
+    // check log levels
+    assertTrue(checkLoggerLevel(loggers, PARENT_LOGGER_NAME, ""));
+    assertTrue(checkLoggerLevel(loggers, CLASS_LOGGER_NAME, "DEBUG"));
+
+    // update parent logger level
+    mparams.set("set", PARENT_LOGGER_NAME + ":TRACE");
+    rsp = client.request(new GenericSolrRequest(SolrRequest.METHOD.GET, 
"/admin/info/logging", mparams));
+
+    @SuppressWarnings({"unchecked"})
+    ArrayList<NamedList<Object>> updatedLoggerLevel = 
(ArrayList<NamedList<Object>>) rsp._get("loggers", null);
+
+    // check new parent logger level
+    assertTrue(checkLoggerLevel(updatedLoggerLevel, PARENT_LOGGER_NAME, 
"TRACE"));
+
     assertEquals(Level.TRACE, 
config.getLoggerConfig(PARENT_LOGGER_NAME).getLevel());
     assertEquals(Level.DEBUG, 
config.getLoggerConfig(CLASS_LOGGER_NAME).getLevel());
     
-    // NOTE: LoggeringHandler doesn't actually "remove" the LoggerConfig, ...
+    // NOTE: LoggingHandler doesn't actually "remove" the LoggerConfig, ...
     // evidently so people using they UI can see that it was explicitly turned 
"OFF" ?
-    assertQ("Remove a level",
-        req(CommonParams.QT,"/admin/logging",  
-            "set", PARENT_LOGGER_NAME+":null")
-        
,"//arr[@name='loggers']/lst/str[.='"+PARENT_LOGGER_NAME+"']/../str[@name='level'][.='OFF']"
-        );
+    mparams.set("set", PARENT_LOGGER_NAME + ":null");
+    rsp = client.request(new GenericSolrRequest(SolrRequest.METHOD.GET, 
"/admin/info/logging", mparams));
+
+    @SuppressWarnings({"unchecked"})
+    ArrayList<NamedList<Object>> removedLoggerLevel = 
(ArrayList<NamedList<Object>>) rsp._get("loggers", null);
+
+    assertTrue(checkLoggerLevel(removedLoggerLevel, PARENT_LOGGER_NAME, 
"OFF"));
+
     assertEquals(Level.OFF, 
config.getLoggerConfig(PARENT_LOGGER_NAME).getLevel());
     assertEquals(Level.DEBUG, 
config.getLoggerConfig(CLASS_LOGGER_NAME).getLevel());
 
-    
+  }
+
+  private boolean checkLoggerLevel(ArrayList<NamedList<Object>> properties, 
String logger, String level) {
+    for (NamedList<Object> property : properties) {
+      String loggerProperty = property._get("name", "").toString();
+      String levelProperty  = property._get("level", "").toString();
+      if (loggerProperty.equals(logger) && levelProperty.equals(level)) {
+        return true;
+      }
+    }
+    return false;
   }
 }
diff --git 
a/solr/core/src/test/org/apache/solr/handler/admin/PropertiesRequestHandlerTest.java
 
b/solr/core/src/test/org/apache/solr/handler/admin/PropertiesRequestHandlerTest.java
index 64da006..be95fb9 100644
--- 
a/solr/core/src/test/org/apache/solr/handler/admin/PropertiesRequestHandlerTest.java
+++ 
b/solr/core/src/test/org/apache/solr/handler/admin/PropertiesRequestHandlerTest.java
@@ -16,11 +16,13 @@
  */
 package org.apache.solr.handler.admin;
 
-import java.io.StringReader;
 
 import org.apache.solr.SolrTestCaseJ4;
-import org.apache.solr.client.solrj.impl.XMLResponseParser;
-import org.apache.solr.common.params.CommonParams;
+import org.apache.solr.client.solrj.SolrClient;
+import org.apache.solr.client.solrj.SolrRequest;
+import org.apache.solr.client.solrj.embedded.EmbeddedSolrServer;
+import org.apache.solr.client.solrj.request.GenericSolrRequest;
+import org.apache.solr.common.params.ModifiableSolrParams;
 import org.apache.solr.common.util.NamedList;
 import org.apache.solr.util.RedactionUtils;
 import org.junit.BeforeClass;
@@ -62,13 +64,11 @@ public class PropertiesRequestHandlerTest extends 
SolrTestCaseJ4 {
 
   @SuppressWarnings({"unchecked"})
   private NamedList<Object> readProperties() throws Exception {
-    String xml = h.query(req(
-        CommonParams.QT, "/admin/properties",
-        CommonParams.WT, "xml"
-    ));
+    SolrClient client = new EmbeddedSolrServer(h.getCore());
 
-    XMLResponseParser parser = new XMLResponseParser();
-    return (NamedList<Object>)
-        parser.processResponse(new StringReader(xml)).get("system.properties");
+    NamedList<Object> properties = client.request(new 
GenericSolrRequest(SolrRequest.METHOD.GET, "/admin/info/properties",
+            new ModifiableSolrParams()));
+
+    return (NamedList<Object>) properties.get("system.properties");
   }
 }
diff --git 
a/solr/core/src/test/org/apache/solr/handler/admin/ThreadDumpHandlerTest.java 
b/solr/core/src/test/org/apache/solr/handler/admin/ThreadDumpHandlerTest.java
index 1828b90..cc7c6a5 100644
--- 
a/solr/core/src/test/org/apache/solr/handler/admin/ThreadDumpHandlerTest.java
+++ 
b/solr/core/src/test/org/apache/solr/handler/admin/ThreadDumpHandlerTest.java
@@ -20,20 +20,26 @@ import java.lang.invoke.MethodHandles;
 import java.lang.management.ManagementFactory;
 import java.util.ArrayList;
 import java.util.List;
+import java.util.Map;
 import java.util.concurrent.CountDownLatch;
 import java.util.concurrent.TimeUnit;
 import java.util.concurrent.locks.ReentrantLock;
 
 import org.apache.solr.SolrTestCaseJ4;
-
+import org.apache.solr.client.solrj.SolrClient;
+import org.apache.solr.client.solrj.SolrRequest;
+import org.apache.solr.client.solrj.embedded.EmbeddedSolrServer;
+import org.apache.solr.client.solrj.request.GenericSolrRequest;
+import org.apache.solr.common.params.ModifiableSolrParams;
+import org.apache.solr.common.util.NamedList;
+import org.junit.BeforeClass;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
-import org.junit.BeforeClass;
 
 /**
  * This test is currently flawed because it only ensures the 'test-*' threads 
don't exit before the asserts,
  * it doesn't adequately ensure they 'start' before the asserts.
- * Fixing the ownershipt should be possible using latches, but fixing the 
'*-blocked' threads may not be possible
+ * Fixing the ownership should be possible using latches, but fixing the 
'*-blocked' threads may not be possible
  * w/o polling
  */
 public class ThreadDumpHandlerTest extends SolrTestCaseJ4 {
@@ -95,12 +101,14 @@ public class ThreadDumpHandlerTest extends SolrTestCaseJ4 {
         failures.add("never saw lockIsHeldLatch released");
         return;
       }
-      assertQ(req("qt", "/admin/threads", "indent", "true")
-              // monitor owner 'ownerT'
-              // (which *MAY* also be waiting on doneWithTestLatch, but may 
not have reached that line yet)
-              , 
"//lst[@name='thread'][str[@name='name'][.='test-thread-monitor-owner']]"
-              + "                     
[arr[@name='monitors-locked']/str[contains(.,'TestMonitorStruct')]]"
-              );
+
+      @SuppressWarnings({"unchecked"})
+      NamedList<Object> threads = (NamedList<Object>) 
readProperties()._get("system/threadDump", null);
+      // monitor owner 'ownerT'
+      // (which *MAY* also be waiting on doneWithTestLatch, but may not have 
reached that line yet)
+      NamedList<Object> thread = 
getThread(threads,"test-thread-monitor-owner");
+      assert thread != null;
+      assertTrue("Thread monitor ownerT: ", thread._get("monitors-locked", 
"").toString().contains("TestMonitorStruct"));
 
       if (checkBlockedThreadViaPolling) {
         log.info("Also checking with blockedT thread setup via polling...");
@@ -116,15 +124,14 @@ public class ThreadDumpHandlerTest extends SolrTestCaseJ4 
{
           Thread.sleep(10); // 10ms at a time, at most 5 sec total
         }
         if (Thread.State.BLOCKED.equals(blockedT.getState())) {
-          assertQ(req("qt", "/admin/threads", "indent", "true")
-                  // same monitor owner 'ownerT'
-                  , 
"//lst[@name='thread'][str[@name='name'][.='test-thread-monitor-owner']]"
-                  + "                     
[arr[@name='monitors-locked']/str[contains(.,'TestMonitorStruct')]]"
-                  // blocked thread 'blockedT', waiting on the monitor
-                  , 
"//lst[@name='thread'][str[@name='name'][.='test-thread-monitor-blocked']]"
-                  + "                     [str[@name='state'][.='BLOCKED']]"
-                  + "                     
[lst[@name='lock-waiting'][lst[@name='owner']/str[.='test-thread-monitor-owner']]]"
-                  );
+          // same monitor owner 'ownerT'
+          assertTrue("Same thread ownerT: ", thread._get("monitors-locked", 
"").toString().contains("ReentrantLock"));
+
+          // blocked thread 'blockedT', waiting on the monitor
+          final NamedList<Object> blockedThread = getThread(threads, 
"test-thread-monitor-blocked");
+          assert blockedThread != null;
+          assertTrue("blocked thread blockedT waiting on the monitor: ", 
blockedThread._getStr("state", null).contains("BLOCKED")
+                  && thread._get("lock-waiting", 
"").toString().contains("test-thread-monitor-owner"));
         }
       }
     } finally {
@@ -193,12 +200,14 @@ public class ThreadDumpHandlerTest extends SolrTestCaseJ4 
{
         failures.add("never saw lockIsHeldLatch released");
         return;
       }
-      assertQ(req("qt", "/admin/threads", "indent", "true")
-              // lock owner 'ownerT'
-              // (which *MAY* also be waiting on doneWithTestLatch, but may 
not have reached that line yet)
-              , 
"//lst[@name='thread'][str[@name='name'][.='test-thread-sync-lock-owner']]"
-              + "                     
[arr[@name='synchronizers-locked']/str[contains(.,'ReentrantLock')]]"
-              );
+
+      @SuppressWarnings({"unchecked"})
+      NamedList<Object> threads = (NamedList<Object>) 
readProperties()._get("system/threadDump", null);
+      // lock owner 'ownerT'
+      // (which *MAY* also be waiting on doneWithTestLatch, but may not have 
reached that line yet)
+      final NamedList<Object> thread = 
getThread(threads,"test-thread-sync-lock-owner");
+      assert thread != null;
+      assertTrue("Thread lock:", thread._get("synchronizers-locked", 
"").toString().contains("ReentrantLock"));
       
       if (checkWaitingThreadViaPolling) {
         log.info("Also checking with blockedT thread setup via polling...");
@@ -214,16 +223,16 @@ public class ThreadDumpHandlerTest extends SolrTestCaseJ4 
{
           Thread.sleep(10); // 10ms at a time, at most 5 sec total
         }
         if (lock.hasQueuedThread(blockedT)) {
-          assertQ(req("qt", "/admin/threads", "indent", "true")
-                  // same lock owner 'ownerT'
-                  , 
"//lst[@name='thread'][str[@name='name'][.='test-thread-sync-lock-owner']]"
-                  + "                     
[arr[@name='synchronizers-locked']/str[contains(.,'ReentrantLock')]]"
-                  // blocked thread 'blockedT', waiting on the lock
-                  , 
"//lst[@name='thread'][str[@name='name'][.='test-thread-sync-lock-blocked']]"
-                  + "                     [str[@name='state'][.='WAITING']]"
-                  + "                     
[lst[@name='lock-waiting'][lst[@name='owner']/str[.='test-thread-sync-lock-owner']]]"
-                  );
-          
+          // lock owner 'ownerT'
+          final NamedList<Object> blockedThread = getThread(threads, 
"test-thread-sync-lock-owner");
+          assert blockedThread != null;
+          assertTrue("Thread locked: ", 
blockedThread._get("synchronizers-locked", 
"").toString().contains("ReentrantLock"));
+
+          // blocked thread 'blockedT', waiting on the lock
+          final NamedList<Object> waitingThread = getThread(threads, 
"test-thread-sync-lock-blocked");
+          assert waitingThread != null;
+          assertTrue("Waiting on the lock: ", waitingThread._getStr("state",  
null).contains("WAITING")
+                  && waitingThread._get("lock-waiting", 
"").toString().contains("test-thread-sync-lock-owner"));
         }
       }
     } finally {
@@ -235,5 +244,26 @@ public class ThreadDumpHandlerTest extends SolrTestCaseJ4 {
       assertFalse("blockedT is still alive", blockedT.isAlive());
     }
   }
+
+  @SuppressWarnings({"unchecked"})
+  private NamedList<Object> readProperties() throws Exception {
+    SolrClient client = new EmbeddedSolrServer(h.getCore());
+
+    NamedList<Object> properties = client.request(new 
GenericSolrRequest(SolrRequest.METHOD.GET, "/admin/info/threads",
+            new ModifiableSolrParams()));
+    return properties;
+  }
+
+  @SuppressWarnings({"unchecked"})
+  private NamedList<Object> getThread(NamedList<Object> threads, String 
threadName) {
+    for (Map.Entry<String, Object> threadEntry : threads) {
+      @SuppressWarnings({"unchecked"})
+      NamedList<Object> thread = (NamedList<Object>) threadEntry.getValue();
+      if (thread._getStr("name",  null).contains(threadName)) {
+        return thread;
+      }
+    }
+    return null;
+  }
   
 }
diff --git a/solr/solr-ref-guide/src/major-changes-in-solr-9.adoc 
b/solr/solr-ref-guide/src/major-changes-in-solr-9.adoc
index 23d3063..d452094 100644
--- a/solr/solr-ref-guide/src/major-changes-in-solr-9.adoc
+++ b/solr/solr-ref-guide/src/major-changes-in-solr-9.adoc
@@ -281,3 +281,6 @@ Users are encouraged to migrate to uniqueBlock() in JSON 
Facet API.  (Mikhail Kh
 Example has been provided in `sample_techproducts_configs` to override 
content-type.
 
 * `min_rf` deprecated in 7.x
+
+* SOLR-15124: Removed three core level admin API endpoints because they are 
already registered at the node level
+where they really belong: /admin/threads, /admin/properties, /admin/logging

Reply via email to