Skip to content

Commit 0efab55

Browse files
igiguereIsabelle Giguereepughgerlowskija
authored
SOLR-17136: Introduce MetricsRequest and SystemInfoRequest to SolrJ (#3955)
Having dedicated SolrRequest implementations for these APIs gives users a much better experience, and allows the server-side code to replace a number of GenericSolrRequest usages that were pretty ugly in the server's "core" module. Co-authored-by: Isabelle Giguere <igiguere71@yahoo.ca> Co-authored-by: Eric Pugh <epugh@opensourceconnections.com> Co-authored-by: Jason Gerlowski <gerlowskija@apache.org>
1 parent 09dbcf2 commit 0efab55

29 files changed

Lines changed: 722 additions & 241 deletions

File tree

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
title: Introduce new SolrJ SolrRequest classes for metrics and "system info" requests.
2+
type: added
3+
authors:
4+
- name: Isabelle Giguère
5+
links:
6+
- name: SOLR-17136
7+
url: https://issues.apache.org/jira/browse/SOLR-17136
Lines changed: 126 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,126 @@
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 java.util.Date;
21+
import java.util.List;
22+
import java.util.Map;
23+
24+
/** Response from /node/system */
25+
public class NodeSystemResponse extends SolrJerseyResponse {
26+
27+
@JsonProperty public String mode;
28+
@JsonProperty public String zkHost;
29+
30+
@JsonProperty("solr_home")
31+
public String solrHome;
32+
33+
@JsonProperty("core_root")
34+
public String coreRoot;
35+
36+
@JsonProperty public String environment;
37+
38+
@JsonProperty(value = "environment_label")
39+
public String environmentLabel;
40+
41+
@JsonProperty(value = "environment_color")
42+
public String environmentColor;
43+
44+
@JsonProperty public String node;
45+
@JsonProperty public Lucene lucene;
46+
@JsonProperty public JVM jvm;
47+
@JsonProperty public Security security;
48+
@JsonProperty public GPU gpu;
49+
@JsonProperty public Map<String, String> system;
50+
51+
/** /node/system/security */
52+
public static class Security {
53+
@JsonProperty public boolean tls;
54+
@JsonProperty public String authenticationPlugin;
55+
@JsonProperty public String authorizationPlugin;
56+
@JsonProperty public String username;
57+
@JsonProperty public List<String> roles;
58+
@JsonProperty public List<String> permissions;
59+
}
60+
61+
/** /node/system/lucene */
62+
public static class Lucene {
63+
@JsonProperty("solr-spec-version")
64+
public String solrSpecVersion;
65+
66+
@JsonProperty("solr-impl-version")
67+
public String solrImplVersion;
68+
69+
@JsonProperty("lucene-spec-version")
70+
public String luceneSpecVersion;
71+
72+
@JsonProperty("lucene-impl-version")
73+
public String luceneImplVersion;
74+
}
75+
76+
/** /node/system/jvm */
77+
public static class JVM extends Vendor {
78+
@JsonProperty public int processors;
79+
@JsonProperty public Vendor jre;
80+
@JsonProperty public Vendor spec;
81+
@JsonProperty public Vendor vm;
82+
@JsonProperty public JvmJmx jmx;
83+
@JsonProperty public JvmMemory memory;
84+
}
85+
86+
public static class JvmMemory {
87+
@JsonProperty public String free;
88+
@JsonProperty public String total;
89+
@JsonProperty public String max;
90+
@JsonProperty public String used;
91+
@JsonProperty public JvmMemoryRaw raw;
92+
}
93+
94+
public static class JvmMemoryRaw extends MemoryRaw {
95+
@JsonProperty public long max;
96+
97+
@JsonProperty("used%")
98+
public double usedPercent;
99+
}
100+
101+
public static class MemoryRaw {
102+
@JsonProperty public long free;
103+
@JsonProperty public long total;
104+
@JsonProperty public long used;
105+
}
106+
107+
public static class Vendor {
108+
@JsonProperty public String name;
109+
@JsonProperty public String vendor;
110+
@JsonProperty public String version;
111+
}
112+
113+
public static class JvmJmx {
114+
@JsonProperty public String classpath;
115+
@JsonProperty public Date startTime;
116+
@JsonProperty public long upTimeMS;
117+
@JsonProperty public List<String> commandLineArgs;
118+
}
119+
120+
public static class GPU {
121+
@JsonProperty public boolean available;
122+
@JsonProperty public long count;
123+
@JsonProperty public MemoryRaw memory;
124+
@JsonProperty Map<String, Object> devices;
125+
}
126+
}

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

Lines changed: 5 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,6 @@
1919

2020
import static org.apache.solr.common.SolrException.ErrorCode.FORBIDDEN;
2121
import static org.apache.solr.common.SolrException.ErrorCode.UNAUTHORIZED;
22-
import static org.apache.solr.common.params.CommonParams.SYSTEM_INFO_PATH;
2322

2423
import java.io.IOException;
2524
import java.net.SocketException;
@@ -38,18 +37,17 @@
3837
import org.apache.commons.cli.Option;
3938
import org.apache.commons.exec.OS;
4039
import org.apache.solr.client.solrj.SolrClient;
41-
import org.apache.solr.client.solrj.SolrRequest;
4240
import org.apache.solr.client.solrj.SolrServerException;
4341
import org.apache.solr.client.solrj.impl.CloudSolrClient;
4442
import org.apache.solr.client.solrj.impl.SolrZkClientTimeout;
4543
import org.apache.solr.client.solrj.jetty.HttpJettySolrClient;
4644
import org.apache.solr.client.solrj.request.CollectionAdminRequest;
4745
import org.apache.solr.client.solrj.request.CoresApi;
48-
import org.apache.solr.client.solrj.request.GenericSolrRequest;
46+
import org.apache.solr.client.solrj.request.SystemInfoRequest;
47+
import org.apache.solr.client.solrj.response.SystemInfoResponse;
4948
import org.apache.solr.common.SolrException;
5049
import org.apache.solr.common.cloud.SolrZkClient;
5150
import org.apache.solr.common.cloud.ZkStateReader;
52-
import org.apache.solr.common.params.CommonParams;
5351
import org.apache.solr.common.util.EnvUtils;
5452
import org.apache.solr.common.util.NamedList;
5553

@@ -249,12 +247,7 @@ public static String getZkHost(CommandLine cli) throws Exception {
249247

250248
try (SolrClient solrClient = getSolrClient(cli)) {
251249
// hit Solr to get system info
252-
NamedList<Object> systemInfo =
253-
solrClient.request(
254-
new GenericSolrRequest(SolrRequest.METHOD.GET, CommonParams.SYSTEM_INFO_PATH));
255-
256-
// convert raw JSON into user-friendly output
257-
Map<String, Object> status = StatusTool.reportStatus(systemInfo, solrClient);
250+
Map<String, Object> status = StatusTool.reportStatus(solrClient);
258251
@SuppressWarnings("unchecked")
259252
Map<String, Object> cloud = (Map<String, Object>) status.get("cloud");
260253
if (cloud != null) {
@@ -357,9 +350,8 @@ public static boolean safeCheckCoreExists(String solrUrl, String coreName, Strin
357350
}
358351

359352
public static boolean isCloudMode(SolrClient solrClient) throws SolrServerException, IOException {
360-
NamedList<Object> systemInfo =
361-
solrClient.request(new GenericSolrRequest(SolrRequest.METHOD.GET, SYSTEM_INFO_PATH));
362-
return "solrcloud".equals(systemInfo.get("mode"));
353+
SystemInfoResponse sysResponse = new SystemInfoRequest().process(solrClient);
354+
return "solrcloud".equals(sysResponse.getMode());
363355
}
364356

365357
public static Path getConfigSetsDir(Path solrInstallDir) {

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

Lines changed: 5 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -29,18 +29,17 @@
2929
import org.apache.commons.io.file.PathUtils;
3030
import org.apache.solr.cli.CommonCLIOptions.DefaultValues;
3131
import org.apache.solr.client.solrj.SolrClient;
32-
import org.apache.solr.client.solrj.SolrRequest;
3332
import org.apache.solr.client.solrj.SolrServerException;
3433
import org.apache.solr.client.solrj.impl.CloudSolrClient;
3534
import org.apache.solr.client.solrj.jetty.HttpJettySolrClient;
3635
import org.apache.solr.client.solrj.request.CollectionAdminRequest;
3736
import org.apache.solr.client.solrj.request.CoreAdminRequest;
38-
import org.apache.solr.client.solrj.request.GenericSolrRequest;
37+
import org.apache.solr.client.solrj.request.SystemInfoRequest;
3938
import org.apache.solr.client.solrj.response.CoreAdminResponse;
39+
import org.apache.solr.client.solrj.response.SystemInfoResponse;
4040
import org.apache.solr.client.solrj.response.json.JsonMapResponseParser;
4141
import org.apache.solr.cloud.ZkConfigSetService;
4242
import org.apache.solr.common.cloud.ZkStateReader;
43-
import org.apache.solr.common.params.CommonParams;
4443
import org.apache.solr.common.util.NamedList;
4544
import org.apache.solr.core.ConfigSetService;
4645
import org.noggit.CharArr;
@@ -157,14 +156,9 @@ protected void createCore(CommandLine cli, SolrClient solrClient) throws Excepti
157156
}
158157
printDefaultConfigsetWarningIfNecessary(cli);
159158

160-
String coreRootDirectory; // usually same as solr home, but not always
161-
162-
NamedList<?> systemInfo =
163-
solrClient.request(
164-
new GenericSolrRequest(SolrRequest.METHOD.GET, CommonParams.SYSTEM_INFO_PATH));
165-
166-
// convert raw JSON into user-friendly output
167-
coreRootDirectory = (String) systemInfo.get("core_root");
159+
SystemInfoResponse sysResponse = (new SystemInfoRequest()).process(solrClient);
160+
// usually same as solr home, but not always
161+
String coreRootDirectory = sysResponse.getCoreRoot();
168162

169163
if (CLIUtils.safeCheckCoreExists(
170164
solrUrl, coreName, cli.getOptionValue(CommonCLIOptions.CREDENTIALS_OPTION))) {

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

Lines changed: 8 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -30,18 +30,16 @@
3030
import org.apache.commons.cli.CommandLine;
3131
import org.apache.commons.cli.Option;
3232
import org.apache.commons.cli.Options;
33-
import org.apache.solr.client.solrj.SolrRequest;
3433
import org.apache.solr.client.solrj.impl.CloudSolrClient;
35-
import org.apache.solr.client.solrj.request.GenericSolrRequest;
3634
import org.apache.solr.client.solrj.request.SolrQuery;
35+
import org.apache.solr.client.solrj.request.SystemInfoRequest;
3736
import org.apache.solr.client.solrj.response.QueryResponse;
37+
import org.apache.solr.client.solrj.response.SystemInfoResponse;
3838
import org.apache.solr.common.cloud.ClusterState;
3939
import org.apache.solr.common.cloud.DocCollection;
4040
import org.apache.solr.common.cloud.Replica;
4141
import org.apache.solr.common.cloud.Slice;
4242
import org.apache.solr.common.cloud.ZkStateReader;
43-
import org.apache.solr.common.params.CommonParams;
44-
import org.apache.solr.common.util.NamedList;
4543
import org.noggit.CharArr;
4644
import org.noggit.JSONWriter;
4745
import org.slf4j.Logger;
@@ -168,15 +166,12 @@ protected void runCloudTool(CloudSolrClient cloudSolrClient, CommandLine cli) th
168166
try (var solrClient =
169167
CLIUtils.getSolrClient(
170168
r.getBaseUrl(), cli.getOptionValue(CommonCLIOptions.CREDENTIALS_OPTION))) {
171-
NamedList<Object> systemInfo =
172-
solrClient.request(
173-
new GenericSolrRequest(
174-
SolrRequest.METHOD.GET, CommonParams.SYSTEM_INFO_PATH));
175-
uptime =
176-
SolrCLI.uptime((Long) systemInfo._get(List.of("jvm", "jmx", "upTimeMS"), null));
177-
String usedMemory = systemInfo._getStr(List.of("jvm", "memory", "used"), null);
178-
String totalMemory = systemInfo._getStr(List.of("jvm", "memory", "total"), null);
179-
memory = usedMemory + " of " + totalMemory;
169+
SystemInfoResponse sysResponse = (new SystemInfoRequest()).process(solrClient);
170+
uptime = SolrCLI.uptime(sysResponse.getJVMUpTimeMillis());
171+
memory =
172+
sysResponse.getHumanReadableJVMMemoryUsed()
173+
+ " of "
174+
+ sysResponse.getHumanReadableJVMMemoryTotal();
180175
}
181176

182177
// if we get here, we can trust the state

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

Lines changed: 17 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -31,10 +31,9 @@
3131
import org.apache.commons.cli.Options;
3232
import org.apache.solr.cli.SolrProcessManager.SolrProcess;
3333
import org.apache.solr.client.solrj.SolrClient;
34-
import org.apache.solr.client.solrj.SolrRequest;
3534
import org.apache.solr.client.solrj.request.CollectionAdminRequest;
36-
import org.apache.solr.client.solrj.request.GenericSolrRequest;
37-
import org.apache.solr.common.params.CommonParams;
35+
import org.apache.solr.client.solrj.request.SystemInfoRequest;
36+
import org.apache.solr.client.solrj.response.SystemInfoResponse;
3837
import org.apache.solr.common.util.NamedList;
3938
import org.apache.solr.common.util.URLUtil;
4039
import org.noggit.CharArr;
@@ -292,42 +291,30 @@ public Map<String, Object> waitToSeeSolrUp(
292291

293292
public Map<String, Object> getStatus(String solrUrl, String credentials) throws Exception {
294293
try (var solrClient = CLIUtils.getSolrClient(solrUrl, credentials)) {
295-
return getStatus(solrClient);
294+
Map<String, Object> status = reportStatus(solrClient);
295+
return status;
296296
}
297297
}
298298

299-
public Map<String, Object> getStatus(SolrClient solrClient) throws Exception {
300-
Map<String, Object> status;
301-
302-
NamedList<Object> systemInfo =
303-
solrClient.request(
304-
new GenericSolrRequest(SolrRequest.METHOD.GET, CommonParams.SYSTEM_INFO_PATH));
305-
// convert raw JSON into user-friendly output
306-
status = reportStatus(systemInfo, solrClient);
307-
308-
return status;
309-
}
310-
311-
public static Map<String, Object> reportStatus(NamedList<Object> info, SolrClient solrClient)
312-
throws Exception {
299+
public static Map<String, Object> reportStatus(SolrClient solrClient) throws Exception {
313300
Map<String, Object> status = new LinkedHashMap<>();
301+
SystemInfoResponse sysResponse = (new SystemInfoRequest()).process(solrClient);
302+
status.put("solr_home", sysResponse.getSolrHome() != null ? sysResponse.getSolrHome() : "?");
303+
status.put("version", sysResponse.getSolrImplVersion());
314304

315-
String solrHome = (String) info.get("solr_home");
316-
status.put("solr_home", solrHome != null ? solrHome : "?");
317-
status.put("version", info._getStr(List.of("lucene", "solr-impl-version"), null));
318-
status.put("startTime", info._getStr(List.of("jvm", "jmx", "startTime"), null));
319-
status.put("uptime", SolrCLI.uptime((Long) info._get(List.of("jvm", "jmx", "upTimeMS"), null)));
305+
status.put("startTime", sysResponse.getJVMStartTime());
306+
status.put("uptime", sysResponse.getJVMUpTimeMillis());
320307

321-
String usedMemory = info._getStr(List.of("jvm", "memory", "used"), null);
322-
String totalMemory = info._getStr(List.of("jvm", "memory", "total"), null);
323-
status.put("memory", usedMemory + " of " + totalMemory);
308+
status.put(
309+
"memory",
310+
sysResponse.getHumanReadableJVMMemoryUsed()
311+
+ " of "
312+
+ sysResponse.getHumanReadableJVMMemoryTotal());
324313

325314
// if this is a Solr in solrcloud mode, gather some basic cluster info
326-
if ("solrcloud".equals(info.get("mode"))) {
327-
String zkHost = (String) info.get("zkHost");
328-
status.put("cloud", getCloudStatus(solrClient, zkHost));
315+
if ("solrcloud".equals(sysResponse.getMode())) {
316+
status.put("cloud", getCloudStatus(solrClient, sysResponse.getZkHost()));
329317
}
330-
331318
return status;
332319
}
333320

solr/core/src/java/org/apache/solr/cloud/api/collections/SplitShardCmd.java

Lines changed: 2 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -39,13 +39,12 @@
3939
import java.util.Set;
4040
import java.util.concurrent.TimeUnit;
4141
import java.util.concurrent.atomic.AtomicReference;
42-
import org.apache.solr.client.solrj.SolrRequest;
4342
import org.apache.solr.client.solrj.SolrResponse;
4443
import org.apache.solr.client.solrj.cloud.DistribStateManager;
4544
import org.apache.solr.client.solrj.cloud.SolrCloudManager;
4645
import org.apache.solr.client.solrj.cloud.VersionedData;
4746
import org.apache.solr.client.solrj.request.CoreAdminRequest;
48-
import org.apache.solr.client.solrj.request.GenericSolrRequest;
47+
import org.apache.solr.client.solrj.request.MetricsRequest;
4948
import org.apache.solr.cloud.DistributedClusterStateUpdater;
5049
import org.apache.solr.cloud.Overseer;
5150
import org.apache.solr.cloud.api.collections.CollectionHandlingUtils.ShardRequestTracker;
@@ -869,10 +868,7 @@ public static void checkDiskSpace(
869868
new ModifiableSolrParams()
870869
.add("key", indexSizeMetricName)
871870
.add("key", freeDiskSpaceMetricName);
872-
SolrResponse rsp =
873-
new GenericSolrRequest(
874-
SolrRequest.METHOD.GET, "/admin/metrics", SolrRequest.SolrRequestType.ADMIN, params)
875-
.process(cloudManager.getSolrClient());
871+
SolrResponse rsp = new MetricsRequest(params).process(cloudManager.getSolrClient());
876872

877873
Number size = (Number) rsp.getResponse()._get(List.of("metrics", indexSizeMetricName), null);
878874
if (size == null) {

0 commit comments

Comments
 (0)