Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 7 additions & 0 deletions changelog/v9.10.0/SOLR-16458.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
title: Add JAX-RS API for retrieving node thread information.
type: added
authors:
- name: Yash Goswami
links:
- name: SOLR-16458
url: https://issues.apache.org/jira/browse/SOLR-16458
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
package org.apache.solr.client.api.endpoint;

import jakarta.ws.rs.GET;
import jakarta.ws.rs.Path;
import org.apache.solr.client.api.model.NodeThreadsResponse;

@Path("/node/threads")
public interface NodeThreadsApi {

@GET
NodeThreadsResponse getThreadDump();
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,97 @@
package org.apache.solr.client.api.model;

import com.fasterxml.jackson.annotation.JsonProperty;
import java.util.List;

public class NodeThreadsResponse extends SolrJerseyResponse {

@JsonProperty("system")
public SystemInfo system;

public static class SystemInfo {

@JsonProperty("threadCount")
public ThreadCount threadCount;

@JsonProperty("deadlocks")

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

i think, in a perfect, world, these Object would be more strongly typed, but I don't have a great sense of how complex that owuld be!

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I agree that strongly typed response fields would be preferable. I’ll look at the existing response models and update this to use appropriate typed classes where practical.

public List<ThreadEntry> deadlocks;

@JsonProperty("threadDump")
public List<ThreadEntry> threadDump;
}

public static class ThreadCount {

@JsonProperty("current")
public long current;

@JsonProperty("peak")
public long peak;

@JsonProperty("daemon")
public long daemon;
}

public static class ThreadEntry {

@JsonProperty("thread")
public ThreadInfo thread;
}

public static class ThreadInfo {

@JsonProperty("id")
public long id;

@JsonProperty("name")
public String name;

@JsonProperty("state")
public String state;

@JsonProperty("lock")
public String lock;

@JsonProperty("lock-waiting")
public LockWaiting lockWaiting;

@JsonProperty("synchronizers-locked")
public List<String> synchronizersLocked;

@JsonProperty("monitors-locked")
public List<String> monitorsLocked;

@JsonProperty("suspended")
public Boolean suspended;

@JsonProperty("native")
public Boolean nativeThread;

@JsonProperty("cpuTime")
public String cpuTime;

@JsonProperty("userTime")
public String userTime;

@JsonProperty("stackTrace")
public List<String> stackTrace;
}

public static class LockWaiting {

@JsonProperty("name")
public String name;

@JsonProperty("owner")
public LockOwner owner;
}

public static class LockOwner {

@JsonProperty("name")
public String name;

@JsonProperty("id")
public long id;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -28,16 +28,15 @@
import java.util.Collection;
import java.util.List;
import java.util.Locale;
import org.apache.solr.api.AnnotatedApi;
import org.apache.solr.api.Api;
import org.apache.solr.common.util.NamedList;
import org.apache.solr.common.util.SimpleOrderedMap;
import org.apache.solr.handler.RequestHandlerBase;
import org.apache.solr.handler.admin.api.NodeThreadsAPI;
import org.apache.solr.request.SolrQueryRequest;
import org.apache.solr.response.SolrQueryResponse;
import org.apache.solr.security.AuthorizationContext;

import org.apache.solr.api.AnnotatedApi;
import org.apache.solr.handler.admin.api.NodeThreadsAPI;
import org.apache.solr.api.Api;
/**
* @since solr 1.2
*/
Expand Down Expand Up @@ -179,12 +178,6 @@ public Category getCategory() {
public Collection<Api> getApis() {
return AnnotatedApi.getApis(new NodeThreadsAPI(this));
}

@Override
public Boolean registerV2() {
return Boolean.TRUE;
}

@Override
public Name getPermissionName(AuthorizationContext request) {
return Name.METRICS_READ_PERM;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,6 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/

package org.apache.solr.handler.admin.api;

import static org.apache.solr.client.solrj.SolrRequest.METHOD.GET;
Expand All @@ -25,12 +24,8 @@
import org.apache.solr.request.SolrQueryRequest;
import org.apache.solr.response.SolrQueryResponse;

/**
* V2 API for triggering a thread dump on the receiving node.
*
* <p>This API (GET /v2/node/threads) is analogous to the v1 /admin/info/threads.
*/
public class NodeThreadsAPI {

private final ThreadDumpHandler handler;

public NodeThreadsAPI(ThreadDumpHandler handler) {
Expand All @@ -41,7 +36,8 @@ public NodeThreadsAPI(ThreadDumpHandler handler) {
path = {"/node/threads"},
method = GET,
permission = METRICS_READ_PERM)
public void triggerThreadDump(SolrQueryRequest req, SolrQueryResponse rsp) throws Exception {
public void triggerThreadDump(
SolrQueryRequest req, SolrQueryResponse rsp) throws Exception {
handler.handleRequestBody(req, rsp);
}
}