Skip to content

Commit 475e723

Browse files
Copilotepugh
andcommitted
Add SolrJ V2 API support for GET /cluster/nodes (ListClusterNodes)
Co-authored-by: epugh <22395+epugh@users.noreply.github.com>
1 parent 746618c commit 475e723

File tree

5 files changed

+119
-9
lines changed

5 files changed

+119
-9
lines changed
Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
/*
2+
* Licensed to the Apache Software Foundation (ASF) under one or more
3+
* contributor license agreements. See the NOTICE file distributed with
4+
* this work for additional information regarding copyright ownership.
5+
* The ASF licenses this file to You under the Apache License, Version 2.0
6+
* (the "License"); you may not use this file except in compliance with
7+
* the License. You may obtain a copy of the License at
8+
*
9+
* http://www.apache.org/licenses/LICENSE-2.0
10+
*
11+
* Unless required by applicable law or agreed to in writing, software
12+
* distributed under the License is distributed on an "AS IS" BASIS,
13+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14+
* See the License for the specific language governing permissions and
15+
* limitations under the License.
16+
*/
17+
package org.apache.solr.client.api.endpoint;
18+
19+
import io.swagger.v3.oas.annotations.Operation;
20+
import jakarta.ws.rs.GET;
21+
import jakarta.ws.rs.Path;
22+
import org.apache.solr.client.api.model.ListClusterNodesResponse;
23+
24+
/** V2 API definition for listing the live nodes in the SolrCloud cluster. */
25+
@Path("/cluster/nodes")
26+
public interface ListClusterNodesApi {
27+
28+
@GET
29+
@Operation(
30+
summary = "List the live nodes in this Solr cluster.",
31+
tags = {"cluster"})
32+
ListClusterNodesResponse listClusterNodes();
33+
}
Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
/*
2+
* Licensed to the Apache Software Foundation (ASF) under one or more
3+
* contributor license agreements. See the NOTICE file distributed with
4+
* this work for additional information regarding copyright ownership.
5+
* The ASF licenses this file to You under the Apache License, Version 2.0
6+
* (the "License"); you may not use this file except in compliance with
7+
* the License. You may obtain a copy of the License at
8+
*
9+
* http://www.apache.org/licenses/LICENSE-2.0
10+
*
11+
* Unless required by applicable law or agreed to in writing, software
12+
* distributed under the License is distributed on an "AS IS" BASIS,
13+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14+
* See the License for the specific language governing permissions and
15+
* limitations under the License.
16+
*/
17+
package org.apache.solr.client.api.model;
18+
19+
import com.fasterxml.jackson.annotation.JsonProperty;
20+
import io.swagger.v3.oas.annotations.media.Schema;
21+
import java.util.Set;
22+
23+
/** Response for the v2 "list cluster nodes" API */
24+
public class ListClusterNodesResponse extends SolrJerseyResponse {
25+
26+
@Schema(description = "The live nodes in the cluster.")
27+
@JsonProperty("nodes")
28+
public Set<String> nodes;
29+
}

solr/core/src/java/org/apache/solr/cli/StatusTool.java

Lines changed: 3 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -30,12 +30,10 @@
3030
import org.apache.commons.cli.Options;
3131
import org.apache.solr.cli.SolrProcessManager.SolrProcess;
3232
import org.apache.solr.client.solrj.SolrClient;
33-
import org.apache.solr.client.solrj.SolrRequest;
33+
import org.apache.solr.client.solrj.request.ClusterApi;
3434
import org.apache.solr.client.solrj.request.CollectionsApi;
35-
import org.apache.solr.client.solrj.request.GenericV2SolrRequest;
3635
import org.apache.solr.client.solrj.request.SystemInfoRequest;
3736
import org.apache.solr.client.solrj.response.SystemInfoResponse;
38-
import org.apache.solr.common.util.NamedList;
3937
import org.apache.solr.common.util.URLUtil;
4038
import org.noggit.CharArr;
4139
import org.noggit.JSONWriter;
@@ -324,17 +322,13 @@ public static Map<String, Object> reportStatus(SolrClient solrClient) throws Exc
324322
*
325323
* <p>Uses GET /cluster/nodes for live node count and GET /collections for collection count.
326324
*/
327-
@SuppressWarnings("unchecked")
328325
private static Map<String, String> getCloudStatus(SolrClient solrClient, String zkHost)
329326
throws Exception {
330327
Map<String, String> cloudStatus = new LinkedHashMap<>();
331328
cloudStatus.put("ZooKeeper", (zkHost != null) ? zkHost : "?");
332329

333-
NamedList<Object> nodesResponse =
334-
solrClient.request(
335-
new GenericV2SolrRequest(
336-
SolrRequest.METHOD.GET, "/cluster/nodes", SolrRequest.SolrRequestType.ADMIN));
337-
var liveNodes = (Collection<?>) nodesResponse.get("nodes");
330+
var nodesResponse = new ClusterApi.ListClusterNodes().process(solrClient);
331+
var liveNodes = nodesResponse != null ? nodesResponse.nodes : null;
338332
cloudStatus.put("liveNodes", String.valueOf(liveNodes != null ? liveNodes.size() : 0));
339333

340334
var collectionsResponse = new CollectionsApi.ListCollections().process(solrClient);

solr/core/src/java/org/apache/solr/handler/admin/CollectionsHandler.java

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -194,6 +194,7 @@
194194
import org.apache.solr.handler.admin.api.ForceLeader;
195195
import org.apache.solr.handler.admin.api.InstallShardData;
196196
import org.apache.solr.handler.admin.api.ListAliases;
197+
import org.apache.solr.handler.admin.api.ListClusterNodes;
197198
import org.apache.solr.handler.admin.api.ListCollectionBackups;
198199
import org.apache.solr.handler.admin.api.ListCollectionSnapshots;
199200
import org.apache.solr.handler.admin.api.ListCollections;
@@ -1370,6 +1371,7 @@ public Collection<Class<? extends JerseyResource>> getJerseyResources() {
13701371
DeleteNode.class,
13711372
ListAliases.class,
13721373
AliasProperty.class,
1374+
ListClusterNodes.class,
13731375
ListCollectionSnapshots.class,
13741376
CreateCollectionSnapshot.class,
13751377
DeleteCollectionSnapshot.class,
Lines changed: 52 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,52 @@
1+
/*
2+
* Licensed to the Apache Software Foundation (ASF) under one or more
3+
* contributor license agreements. See the NOTICE file distributed with
4+
* this work for additional information regarding copyright ownership.
5+
* The ASF licenses this file to You under the Apache License, Version 2.0
6+
* (the "License"); you may not use this file except in compliance with
7+
* the License. You may obtain a copy of the License at
8+
*
9+
* http://www.apache.org/licenses/LICENSE-2.0
10+
*
11+
* Unless required by applicable law or agreed to in writing, software
12+
* distributed under the License is distributed on an "AS IS" BASIS,
13+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14+
* See the License for the specific language governing permissions and
15+
* limitations under the License.
16+
*/
17+
package org.apache.solr.handler.admin.api;
18+
19+
import static org.apache.solr.security.PermissionNameProvider.Name.COLL_READ_PERM;
20+
21+
import jakarta.inject.Inject;
22+
import org.apache.solr.client.api.endpoint.ListClusterNodesApi;
23+
import org.apache.solr.client.api.model.ListClusterNodesResponse;
24+
import org.apache.solr.core.CoreContainer;
25+
import org.apache.solr.jersey.PermissionName;
26+
import org.apache.solr.request.SolrQueryRequest;
27+
import org.apache.solr.response.SolrQueryResponse;
28+
29+
/**
30+
* V2 API for listing the live nodes in the SolrCloud cluster.
31+
*
32+
* <p>This API (GET /v2/cluster/nodes) is equivalent to the v1 CLUSTERSTATUS action filtered to
33+
* live_nodes.
34+
*/
35+
public class ListClusterNodes extends AdminAPIBase implements ListClusterNodesApi {
36+
37+
@Inject
38+
public ListClusterNodes(
39+
CoreContainer coreContainer, SolrQueryRequest req, SolrQueryResponse rsp) {
40+
super(coreContainer, req, rsp);
41+
}
42+
43+
@Override
44+
@PermissionName(COLL_READ_PERM)
45+
public ListClusterNodesResponse listClusterNodes() {
46+
final ListClusterNodesResponse response =
47+
instantiateJerseyResponse(ListClusterNodesResponse.class);
48+
validateZooKeeperAwareCoreContainer(coreContainer);
49+
response.nodes = coreContainer.getZkController().getClusterState().getLiveNodes();
50+
return response;
51+
}
52+
}

0 commit comments

Comments
 (0)