Skip to content

Commit 64e029e

Browse files
authored
SOLR-18091: Separate out core specific info into it's own CoreInfoHandler (#4084)
SystemInfoHandler is loaded at the node/container level, while the core specific CoreInfoHandler is configured via ImplicitPlugins.json. This matches our pattern of other handlers.
1 parent 4f40e97 commit 64e029e

File tree

15 files changed

+457
-139
lines changed

15 files changed

+457
-139
lines changed
Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
# See https://github.com/apache/solr/blob/main/dev-docs/changelog.adoc
2+
title: Provide seperate request handler SystemInfoHandler for /solr/admin/info/system from CoreInfoHandler for /solr/<collection-name>/admin/info
3+
type: other # added, changed, fixed, deprecated, removed, dependency_update, security, other
4+
authors:
5+
- name: Eric Pugh
6+
links:
7+
- name: SOLR-18091
8+
url: https://issues.apache.org/jira/browse/SOLR-18091

solr/api/src/java/org/apache/solr/client/api/model/NodeSystemResponse.java

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,7 @@
2525
public class NodeSystemResponse extends SolrJerseyResponse {
2626

2727
@JsonProperty public String mode;
28+
@JsonProperty public String host;
2829
@JsonProperty public String zkHost;
2930

3031
@JsonProperty("solr_home")
Lines changed: 91 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,91 @@
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;
18+
19+
import java.io.IOException;
20+
import java.lang.invoke.MethodHandles;
21+
import java.nio.file.Path;
22+
import java.util.Date;
23+
import org.apache.solr.common.util.SimpleOrderedMap;
24+
import org.apache.solr.core.SolrCore;
25+
import org.apache.solr.handler.RequestHandlerBase;
26+
import org.apache.solr.request.SolrQueryRequest;
27+
import org.apache.solr.response.SolrQueryResponse;
28+
import org.apache.solr.schema.IndexSchema;
29+
import org.apache.solr.security.AuthorizationContext;
30+
import org.slf4j.Logger;
31+
import org.slf4j.LoggerFactory;
32+
33+
/**
34+
* This handler returns core level info. See {@link org.apache.solr.handler.admin.SystemInfoHandler}
35+
*/
36+
public class CoreInfoHandler extends RequestHandlerBase {
37+
private static final Logger log = LoggerFactory.getLogger(MethodHandles.lookup().lookupClass());
38+
39+
@Override
40+
public String getDescription() {
41+
return "Get Core Info";
42+
}
43+
44+
@Override
45+
public Category getCategory() {
46+
return Category.ADMIN;
47+
}
48+
49+
@Override
50+
public Name getPermissionName(AuthorizationContext request) {
51+
return Name.CONFIG_READ_PERM;
52+
}
53+
54+
@Override
55+
public void handleRequestBody(SolrQueryRequest req, SolrQueryResponse rsp) throws Exception {
56+
rsp.setHttpCaching(false);
57+
SolrCore core = req.getCore();
58+
59+
rsp.add("core", getCoreInfo(core, req.getSchema()));
60+
}
61+
62+
private SimpleOrderedMap<Object> getCoreInfo(SolrCore core, IndexSchema schema) {
63+
SimpleOrderedMap<Object> info = new SimpleOrderedMap<>();
64+
65+
info.add("schema", schema != null ? schema.getSchemaName() : "no schema!");
66+
67+
// Now
68+
info.add("now", new Date());
69+
70+
// Start Time
71+
info.add("start", core.getStartTimeStamp());
72+
73+
// Solr Home
74+
SimpleOrderedMap<Object> dirs = new SimpleOrderedMap<>();
75+
dirs.add("cwd", Path.of(System.getProperty("user.dir")).toAbsolutePath().toString());
76+
dirs.add("instance", core.getInstancePath().toString());
77+
try {
78+
dirs.add("data", core.getDirectoryFactory().normalize(core.getDataDir()));
79+
} catch (IOException e) {
80+
log.warn("Problem getting the normalized data directory path", e);
81+
}
82+
dirs.add("dirimpl", core.getDirectoryFactory().getClass().getName());
83+
try {
84+
dirs.add("index", core.getDirectoryFactory().normalize(core.getIndexDir()));
85+
} catch (IOException e) {
86+
log.warn("Problem getting the normalized index directory path", e);
87+
}
88+
info.add("directory", dirs);
89+
return info;
90+
}
91+
}

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

Lines changed: 9 additions & 52 deletions
Original file line numberDiff line numberDiff line change
@@ -22,15 +22,13 @@
2222
import java.beans.IntrospectionException;
2323
import java.beans.Introspector;
2424
import java.beans.PropertyDescriptor;
25-
import java.io.IOException;
2625
import java.lang.invoke.MethodHandles;
2726
import java.lang.management.ManagementFactory;
2827
import java.lang.management.OperatingSystemMXBean;
2928
import java.lang.management.PlatformManagedObject;
3029
import java.lang.management.RuntimeMXBean;
3130
import java.lang.reflect.Method;
3231
import java.net.InetAddress;
33-
import java.nio.file.Path;
3432
import java.text.DecimalFormat;
3533
import java.text.DecimalFormatSymbols;
3634
import java.util.ArrayList;
@@ -58,7 +56,6 @@
5856
import org.apache.solr.metrics.GpuMetricsProvider;
5957
import org.apache.solr.request.SolrQueryRequest;
6058
import org.apache.solr.response.SolrQueryResponse;
61-
import org.apache.solr.schema.IndexSchema;
6259
import org.apache.solr.security.AuthorizationContext;
6360
import org.apache.solr.security.AuthorizationPlugin;
6461
import org.apache.solr.security.PKIAuthenticationPlugin;
@@ -69,9 +66,8 @@
6966
import org.slf4j.LoggerFactory;
7067

7168
/**
72-
* This handler returns system info
73-
*
74-
* @since solr 1.2
69+
* This handler returns node/container level info. See {@link
70+
* org.apache.solr.handler.admin.CoreInfoHandler}
7571
*/
7672
public class SystemInfoHandler extends RequestHandlerBase {
7773
private static final Logger log = LoggerFactory.getLogger(MethodHandles.lookup().lookupClass());
@@ -103,10 +99,6 @@ public class SystemInfoHandler extends RequestHandlerBase {
10399

104100
private CoreContainer cc;
105101

106-
public SystemInfoHandler() {
107-
this(null);
108-
}
109-
110102
public SystemInfoHandler(CoreContainer cc) {
111103
super();
112104
this.cc = cc;
@@ -218,13 +210,14 @@ private void initHostname() {
218210
@Override
219211
public void handleRequestBody(SolrQueryRequest req, SolrQueryResponse rsp) throws Exception {
220212
rsp.setHttpCaching(false);
221-
SolrCore core = req.getCore();
222213
if (AdminHandlersProxy.maybeProxyToNodes(req, rsp, getCoreContainer(req))) {
223214
return; // Request was proxied to other node
224215
}
225-
if (core != null) rsp.add("core", getCoreInfo(core, req.getSchema()));
226216
boolean solrCloudMode = getCoreContainer(req).isZooKeeperAware();
227217
rsp.add("mode", solrCloudMode ? "solrcloud" : "std");
218+
219+
rsp.add("host", hostname);
220+
228221
if (solrCloudMode) {
229222
rsp.add("zkHost", getCoreContainer(req).getZkController().getZkServerAddress());
230223
}
@@ -262,42 +255,6 @@ private CoreContainer getCoreContainer(SolrQueryRequest req) {
262255
return coreContainer == null ? cc : coreContainer;
263256
}
264257

265-
/** Get system info */
266-
private SimpleOrderedMap<Object> getCoreInfo(SolrCore core, IndexSchema schema) {
267-
SimpleOrderedMap<Object> info = new SimpleOrderedMap<>();
268-
269-
info.add("schema", schema != null ? schema.getSchemaName() : "no schema!");
270-
271-
// Host
272-
info.add("host", hostname);
273-
274-
// Now
275-
info.add("now", new Date());
276-
277-
// Start Time
278-
info.add("start", core.getStartTimeStamp());
279-
280-
// Solr Home
281-
SimpleOrderedMap<Object> dirs = new SimpleOrderedMap<>();
282-
dirs.add("cwd", Path.of(System.getProperty("user.dir")).toAbsolutePath().toString());
283-
dirs.add("instance", core.getInstancePath().toString());
284-
try {
285-
dirs.add("data", core.getDirectoryFactory().normalize(core.getDataDir()));
286-
} catch (IOException e) {
287-
log.warn("Problem getting the normalized data directory path", e);
288-
dirs.add("data", "N/A");
289-
}
290-
dirs.add("dirimpl", core.getDirectoryFactory().getClass().getName());
291-
try {
292-
dirs.add("index", core.getDirectoryFactory().normalize(core.getIndexDir()));
293-
} catch (IOException e) {
294-
log.warn("Problem getting the normalized index directory path", e);
295-
dirs.add("index", "N/A");
296-
}
297-
info.add("directory", dirs);
298-
return info;
299-
}
300-
301258
/** Get system info */
302259
public static SimpleOrderedMap<Object> getSystemInfo() {
303260
SimpleOrderedMap<Object> info = new SimpleOrderedMap<>();
@@ -480,13 +437,13 @@ private static String humanReadableUnits(long bytes, DecimalFormat df) {
480437
String newSizeAndUnits;
481438

482439
if (bytes / ONE_GB > 0) {
483-
newSizeAndUnits = String.valueOf(df.format((float) bytes / ONE_GB)) + " GB";
440+
newSizeAndUnits = df.format((float) bytes / ONE_GB) + " GB";
484441
} else if (bytes / ONE_MB > 0) {
485-
newSizeAndUnits = String.valueOf(df.format((float) bytes / ONE_MB)) + " MB";
442+
newSizeAndUnits = df.format((float) bytes / ONE_MB) + " MB";
486443
} else if (bytes / ONE_KB > 0) {
487-
newSizeAndUnits = String.valueOf(df.format((float) bytes / ONE_KB)) + " KB";
444+
newSizeAndUnits = df.format((float) bytes / ONE_KB) + " KB";
488445
} else {
489-
newSizeAndUnits = String.valueOf(bytes) + " bytes";
446+
newSizeAndUnits = bytes + " bytes";
490447
}
491448

492449
return newSizeAndUnits;

solr/core/src/resources/ImplicitPlugins.json

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -73,9 +73,9 @@
7373
"class": "solr.LukeRequestHandler",
7474
"useParams":"_ADMIN_LUKE"
7575
},
76-
"/admin/system": {
77-
"class": "solr.SystemInfoHandler",
78-
"useParams":"_ADMIN_SYSTEM"
76+
"/admin/info": {
77+
"class": "solr.CoreInfoHandler",
78+
"useParams":"_ADMIN_CORE"
7979
},
8080
"/admin/file": {
8181
"class": "solr.ShowFileRequestHandler",

solr/core/src/test/org/apache/solr/core/SolrCoreTest.java

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -101,7 +101,7 @@ public void testImplicitPlugins() {
101101
++ihCount;
102102
assertEquals(pathToClassMap.get("/admin/segments"), "solr.SegmentsInfoRequestHandler");
103103
++ihCount;
104-
assertEquals(pathToClassMap.get("/admin/system"), "solr.SystemInfoHandler");
104+
assertEquals(pathToClassMap.get("/admin/info"), "solr.CoreInfoHandler");
105105
++ihCount;
106106
assertEquals(pathToClassMap.get("/config"), "solr.SolrConfigHandler");
107107
++ihCount;
@@ -196,7 +196,7 @@ public void testRefCount() {
196196
c1.close();
197197
cores.shutdown();
198198
assertEquals("Refcount != 0", 0, core.getOpenCount());
199-
assertTrue("Handler not closed", core.isClosed() && handler1.closed == true);
199+
assertTrue("Handler not closed", core.isClosed() && handler1.closed);
200200
}
201201

202202
@Test
@@ -263,7 +263,7 @@ public Integer call() {
263263

264264
cores.shutdown();
265265
assertEquals("Refcount != 0", 0, core.getOpenCount());
266-
assertTrue("Handler not closed", core.isClosed() && handler1.closed == true);
266+
assertTrue("Handler not closed", core.isClosed() && handler1.closed);
267267

268268
service.shutdown();
269269
assertTrue("Running for too long...", service.awaitTermination(60, TimeUnit.SECONDS));

solr/core/src/test/org/apache/solr/core/TestSolrConfigHandler.java

Lines changed: 5 additions & 36 deletions
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,6 @@
1919
import static java.util.Arrays.asList;
2020
import static org.apache.solr.common.util.Utils.getObjectByPath;
2121

22-
import java.io.FileOutputStream;
2322
import java.io.IOException;
2423
import java.io.InputStream;
2524
import java.io.StringReader;
@@ -34,8 +33,6 @@
3433
import java.util.SortedMap;
3534
import java.util.TreeMap;
3635
import java.util.concurrent.TimeUnit;
37-
import java.util.zip.ZipEntry;
38-
import java.util.zip.ZipOutputStream;
3936
import org.apache.commons.io.file.PathUtils;
4037
import org.apache.solr.SolrTestCaseJ4;
4138
import org.apache.solr.client.solrj.impl.CloudSolrClient;
@@ -66,9 +63,6 @@ public class TestSolrConfigHandler extends RestTestBase {
6663

6764
private static final Logger log = LoggerFactory.getLogger(MethodHandles.lookup().lookupClass());
6865

69-
private static final String collection = "collection1";
70-
private static final String confDir = collection + "/conf";
71-
7266
public static ByteBuffer getFileContent(String f) throws IOException {
7367
return getFileContent(f, true);
7468
}
@@ -89,31 +83,6 @@ public static ByteBuffer getFileContent(String f, boolean loadFromClassPath) thr
8983
return jar;
9084
}
9185

92-
public static ByteBuffer persistZip(String loc, Class<?>... classes) throws IOException {
93-
ByteBuffer jar = generateZip(classes);
94-
try (FileOutputStream fos = new FileOutputStream(loc)) {
95-
fos.write(jar.array(), jar.arrayOffset(), jar.limit());
96-
fos.flush();
97-
}
98-
return jar;
99-
}
100-
101-
public static ByteBuffer generateZip(Class<?>... classes) throws IOException {
102-
Utils.BAOS bos = new Utils.BAOS();
103-
try (ZipOutputStream zipOut = new ZipOutputStream(bos)) {
104-
zipOut.setLevel(ZipOutputStream.DEFLATED);
105-
for (Class<?> c : classes) {
106-
String path = c.getName().replace('.', '/').concat(".class");
107-
ZipEntry entry = new ZipEntry(path);
108-
ByteBuffer b = Utils.toByteArray(c.getClassLoader().getResourceAsStream(path));
109-
zipOut.putNextEntry(entry);
110-
zipOut.write(b.array(), b.arrayOffset(), b.limit());
111-
zipOut.closeEntry();
112-
}
113-
}
114-
return bos.getByteBuffer();
115-
}
116-
11786
@Before
11887
public void before() throws Exception {
11988
Path tmpSolrHome = createTempDir();
@@ -152,7 +121,7 @@ public void testProperty() throws Exception {
152121
RestTestHarness harness = restTestHarness;
153122
MapWriter confMap = getRespMap("/config", harness);
154123
assertNotNull(confMap._get(asList("config", "requestHandler", "/admin/luke"), null));
155-
assertNotNull(confMap._get(asList("config", "requestHandler", "/admin/system"), null));
124+
assertNotNull(confMap._get(asList("config", "requestHandler", "/admin/info"), null));
156125
assertNotNull(confMap._get(asList("config", "requestHandler", "/admin/file"), null));
157126
assertNotNull(confMap._get(asList("config", "requestHandler", "/admin/ping"), null));
158127

@@ -1009,7 +978,7 @@ public static LinkedHashMapWriter getRespMap(String path, RestTestHarness restHa
1009978

1010979
public void testCacheDisableSolrConfig() throws Exception {
1011980
RESTfulServerProvider oldProvider = restTestHarness.getServerProvider();
1012-
restTestHarness.setServerProvider(() -> getBaseUrl());
981+
restTestHarness.setServerProvider(RestTestBase::getBaseUrl);
1013982
String prometheusMetrics = restTestHarness.query("/admin/metrics?wt=prometheus");
1014983
assertTrue(
1015984
"fieldValueCache metrics should be present",
@@ -1030,7 +999,7 @@ public void testSetPropertyCacheSize() throws Exception {
1030999
MapWriter overlay = getRespMap("/config/overlay", restTestHarness);
10311000
assertEquals("399", overlay._getStr("overlay/props/query/documentCache/size"));
10321001
// Setting size only will not enable the cache
1033-
restTestHarness.setServerProvider(() -> getBaseUrl());
1002+
restTestHarness.setServerProvider(RestTestBase::getBaseUrl);
10341003

10351004
String prometheusMetrics = restTestHarness.query("/admin/metrics?wt=prometheus");
10361005
assertFalse(prometheusMetrics.contains("cache_name=\"documentCache\""));
@@ -1043,7 +1012,7 @@ public void testSetPropertyEnableAndDisableCache() throws Exception {
10431012
// Enabling Cache
10441013
String payload = "{'set-property' : { 'query.documentCache.enabled': true} }";
10451014
runConfigCommand(restTestHarness, "/config", payload);
1046-
restTestHarness.setServerProvider(() -> getBaseUrl());
1015+
restTestHarness.setServerProvider(RestTestBase::getBaseUrl);
10471016

10481017
String prometheusMetrics = restTestHarness.query("/admin/metrics?wt=prometheus");
10491018
assertTrue(prometheusMetrics.contains("name=\"documentCache\""));
@@ -1053,7 +1022,7 @@ public void testSetPropertyEnableAndDisableCache() throws Exception {
10531022
restTestHarness.setServerProvider(oldProvider);
10541023

10551024
runConfigCommand(restTestHarness, "/config", payload);
1056-
restTestHarness.setServerProvider(() -> getBaseUrl());
1025+
restTestHarness.setServerProvider(RestTestBase::getBaseUrl);
10571026

10581027
prometheusMetrics = restTestHarness.query("/admin/metrics?wt=prometheus");
10591028
assertFalse(prometheusMetrics.contains("name=\"documentCache\""));

0 commit comments

Comments
 (0)