Skip to content
Merged
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
8 changes: 8 additions & 0 deletions changelog/unreleased/SOLR-18091.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
# See https://github.com/apache/solr/blob/main/dev-docs/changelog.adoc
title: Provide seperate request handler SystemInfoHandler for /solr/admin/info/system from CoreInfoHandler for /solr/<collection-name>/admin/info
type: other # added, changed, fixed, deprecated, removed, dependency_update, security, other
authors:
- name: Eric Pugh
links:
- name: SOLR-18091
url: https://issues.apache.org/jira/browse/SOLR-18091
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@
public class NodeSystemResponse extends SolrJerseyResponse {

@JsonProperty public String mode;
@JsonProperty public String host;
@JsonProperty public String zkHost;

@JsonProperty("solr_home")
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,91 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.apache.solr.handler.admin;

import java.io.IOException;
import java.lang.invoke.MethodHandles;
import java.nio.file.Path;
import java.util.Date;
import org.apache.solr.common.util.SimpleOrderedMap;
import org.apache.solr.core.SolrCore;
import org.apache.solr.handler.RequestHandlerBase;
import org.apache.solr.request.SolrQueryRequest;
import org.apache.solr.response.SolrQueryResponse;
import org.apache.solr.schema.IndexSchema;
import org.apache.solr.security.AuthorizationContext;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

/**
* This handler returns core level info. See {@link org.apache.solr.handler.admin.SystemInfoHandler}
*/
public class CoreInfoHandler extends RequestHandlerBase {
private static final Logger log = LoggerFactory.getLogger(MethodHandles.lookup().lookupClass());

@Override
public String getDescription() {
return "Get Core Info";
}

@Override
public Category getCategory() {
return Category.ADMIN;
}

@Override
public Name getPermissionName(AuthorizationContext request) {
return Name.CONFIG_READ_PERM;
}

@Override
public void handleRequestBody(SolrQueryRequest req, SolrQueryResponse rsp) throws Exception {
rsp.setHttpCaching(false);
Copy link
Contributor Author

Choose a reason for hiding this comment

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

Does this request handler need if (AdminHandlersProxy.maybeProxyToNodes(req, rsp, getCoreContainer(req))) { like SystemInfoHandler has? Is that soemthing every class needs?

SolrCore core = req.getCore();

rsp.add("core", getCoreInfo(core, req.getSchema()));
}

private SimpleOrderedMap<Object> getCoreInfo(SolrCore core, IndexSchema schema) {
SimpleOrderedMap<Object> info = new SimpleOrderedMap<>();

info.add("schema", schema != null ? schema.getSchemaName() : "no schema!");

// Now
info.add("now", new Date());

// Start Time
info.add("start", core.getStartTimeStamp());

// Solr Home
SimpleOrderedMap<Object> dirs = new SimpleOrderedMap<>();
dirs.add("cwd", Path.of(System.getProperty("user.dir")).toAbsolutePath().toString());
dirs.add("instance", core.getInstancePath().toString());
try {
dirs.add("data", core.getDirectoryFactory().normalize(core.getDataDir()));
} catch (IOException e) {
log.warn("Problem getting the normalized data directory path", e);
}
dirs.add("dirimpl", core.getDirectoryFactory().getClass().getName());
try {
dirs.add("index", core.getDirectoryFactory().normalize(core.getIndexDir()));
} catch (IOException e) {
log.warn("Problem getting the normalized index directory path", e);
}
info.add("directory", dirs);
return info;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -22,15 +22,13 @@
import java.beans.IntrospectionException;
import java.beans.Introspector;
import java.beans.PropertyDescriptor;
import java.io.IOException;
import java.lang.invoke.MethodHandles;
import java.lang.management.ManagementFactory;
import java.lang.management.OperatingSystemMXBean;
import java.lang.management.PlatformManagedObject;
import java.lang.management.RuntimeMXBean;
import java.lang.reflect.Method;
import java.net.InetAddress;
import java.nio.file.Path;
import java.text.DecimalFormat;
import java.text.DecimalFormatSymbols;
import java.util.ArrayList;
Expand Down Expand Up @@ -58,7 +56,6 @@
import org.apache.solr.metrics.GpuMetricsProvider;
import org.apache.solr.request.SolrQueryRequest;
import org.apache.solr.response.SolrQueryResponse;
import org.apache.solr.schema.IndexSchema;
import org.apache.solr.security.AuthorizationContext;
import org.apache.solr.security.AuthorizationPlugin;
import org.apache.solr.security.PKIAuthenticationPlugin;
Expand All @@ -69,9 +66,8 @@
import org.slf4j.LoggerFactory;

/**
* This handler returns system info
*
* @since solr 1.2
* This handler returns node/container level info. See {@link
* org.apache.solr.handler.admin.CoreInfoHandler}
*/
public class SystemInfoHandler extends RequestHandlerBase {
private static final Logger log = LoggerFactory.getLogger(MethodHandles.lookup().lookupClass());
Expand Down Expand Up @@ -103,10 +99,6 @@ public class SystemInfoHandler extends RequestHandlerBase {

private CoreContainer cc;

public SystemInfoHandler() {
this(null);
}

public SystemInfoHandler(CoreContainer cc) {
super();
this.cc = cc;
Expand Down Expand Up @@ -218,13 +210,14 @@ private void initHostname() {
@Override
public void handleRequestBody(SolrQueryRequest req, SolrQueryResponse rsp) throws Exception {
rsp.setHttpCaching(false);
SolrCore core = req.getCore();
if (AdminHandlersProxy.maybeProxyToNodes(req, rsp, getCoreContainer(req))) {
return; // Request was proxied to other node
}
if (core != null) rsp.add("core", getCoreInfo(core, req.getSchema()));
boolean solrCloudMode = getCoreContainer(req).isZooKeeperAware();
rsp.add("mode", solrCloudMode ? "solrcloud" : "std");

rsp.add("host", hostname);

if (solrCloudMode) {
rsp.add("zkHost", getCoreContainer(req).getZkController().getZkServerAddress());
}
Expand Down Expand Up @@ -262,42 +255,6 @@ private CoreContainer getCoreContainer(SolrQueryRequest req) {
return coreContainer == null ? cc : coreContainer;
}

/** Get system info */
private SimpleOrderedMap<Object> getCoreInfo(SolrCore core, IndexSchema schema) {
SimpleOrderedMap<Object> info = new SimpleOrderedMap<>();

info.add("schema", schema != null ? schema.getSchemaName() : "no schema!");

// Host
info.add("host", hostname);

// Now
info.add("now", new Date());

// Start Time
info.add("start", core.getStartTimeStamp());

// Solr Home
SimpleOrderedMap<Object> dirs = new SimpleOrderedMap<>();
dirs.add("cwd", Path.of(System.getProperty("user.dir")).toAbsolutePath().toString());
dirs.add("instance", core.getInstancePath().toString());
try {
dirs.add("data", core.getDirectoryFactory().normalize(core.getDataDir()));
} catch (IOException e) {
log.warn("Problem getting the normalized data directory path", e);
dirs.add("data", "N/A");
}
dirs.add("dirimpl", core.getDirectoryFactory().getClass().getName());
try {
dirs.add("index", core.getDirectoryFactory().normalize(core.getIndexDir()));
} catch (IOException e) {
log.warn("Problem getting the normalized index directory path", e);
dirs.add("index", "N/A");
}
info.add("directory", dirs);
return info;
}

/** Get system info */
public static SimpleOrderedMap<Object> getSystemInfo() {
SimpleOrderedMap<Object> info = new SimpleOrderedMap<>();
Expand Down Expand Up @@ -480,13 +437,13 @@ private static String humanReadableUnits(long bytes, DecimalFormat df) {
String newSizeAndUnits;

if (bytes / ONE_GB > 0) {
newSizeAndUnits = String.valueOf(df.format((float) bytes / ONE_GB)) + " GB";
newSizeAndUnits = df.format((float) bytes / ONE_GB) + " GB";
} else if (bytes / ONE_MB > 0) {
newSizeAndUnits = String.valueOf(df.format((float) bytes / ONE_MB)) + " MB";
newSizeAndUnits = df.format((float) bytes / ONE_MB) + " MB";
} else if (bytes / ONE_KB > 0) {
newSizeAndUnits = String.valueOf(df.format((float) bytes / ONE_KB)) + " KB";
newSizeAndUnits = df.format((float) bytes / ONE_KB) + " KB";
} else {
newSizeAndUnits = String.valueOf(bytes) + " bytes";
newSizeAndUnits = bytes + " bytes";
}

return newSizeAndUnits;
Expand Down
6 changes: 3 additions & 3 deletions solr/core/src/resources/ImplicitPlugins.json
Original file line number Diff line number Diff line change
Expand Up @@ -73,9 +73,9 @@
"class": "solr.LukeRequestHandler",
"useParams":"_ADMIN_LUKE"
},
"/admin/system": {
"class": "solr.SystemInfoHandler",
"useParams":"_ADMIN_SYSTEM"
"/admin/info": {
"class": "solr.CoreInfoHandler",
"useParams":"_ADMIN_CORE"
},
"/admin/file": {
"class": "solr.ShowFileRequestHandler",
Expand Down
6 changes: 3 additions & 3 deletions solr/core/src/test/org/apache/solr/core/SolrCoreTest.java
Original file line number Diff line number Diff line change
Expand Up @@ -101,7 +101,7 @@ public void testImplicitPlugins() {
++ihCount;
assertEquals(pathToClassMap.get("/admin/segments"), "solr.SegmentsInfoRequestHandler");
++ihCount;
assertEquals(pathToClassMap.get("/admin/system"), "solr.SystemInfoHandler");
assertEquals(pathToClassMap.get("/admin/info"), "solr.CoreInfoHandler");
++ihCount;
assertEquals(pathToClassMap.get("/config"), "solr.SolrConfigHandler");
++ihCount;
Expand Down Expand Up @@ -196,7 +196,7 @@ public void testRefCount() {
c1.close();
cores.shutdown();
assertEquals("Refcount != 0", 0, core.getOpenCount());
assertTrue("Handler not closed", core.isClosed() && handler1.closed == true);
assertTrue("Handler not closed", core.isClosed() && handler1.closed);
}

@Test
Expand Down Expand Up @@ -263,7 +263,7 @@ public Integer call() {

cores.shutdown();
assertEquals("Refcount != 0", 0, core.getOpenCount());
assertTrue("Handler not closed", core.isClosed() && handler1.closed == true);
assertTrue("Handler not closed", core.isClosed() && handler1.closed);

service.shutdown();
assertTrue("Running for too long...", service.awaitTermination(60, TimeUnit.SECONDS));
Expand Down
41 changes: 5 additions & 36 deletions solr/core/src/test/org/apache/solr/core/TestSolrConfigHandler.java
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,6 @@
import static java.util.Arrays.asList;
import static org.apache.solr.common.util.Utils.getObjectByPath;

import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.StringReader;
Expand All @@ -34,8 +33,6 @@
import java.util.SortedMap;
import java.util.TreeMap;
import java.util.concurrent.TimeUnit;
import java.util.zip.ZipEntry;
import java.util.zip.ZipOutputStream;
import org.apache.commons.io.file.PathUtils;
import org.apache.solr.SolrTestCaseJ4;
import org.apache.solr.client.solrj.impl.CloudSolrClient;
Expand Down Expand Up @@ -66,9 +63,6 @@ public class TestSolrConfigHandler extends RestTestBase {

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

private static final String collection = "collection1";
private static final String confDir = collection + "/conf";

public static ByteBuffer getFileContent(String f) throws IOException {
return getFileContent(f, true);
}
Expand All @@ -89,31 +83,6 @@ public static ByteBuffer getFileContent(String f, boolean loadFromClassPath) thr
return jar;
}

public static ByteBuffer persistZip(String loc, Class<?>... classes) throws IOException {
ByteBuffer jar = generateZip(classes);
try (FileOutputStream fos = new FileOutputStream(loc)) {
fos.write(jar.array(), jar.arrayOffset(), jar.limit());
fos.flush();
}
return jar;
}

public static ByteBuffer generateZip(Class<?>... classes) throws IOException {
Utils.BAOS bos = new Utils.BAOS();
try (ZipOutputStream zipOut = new ZipOutputStream(bos)) {
zipOut.setLevel(ZipOutputStream.DEFLATED);
for (Class<?> c : classes) {
String path = c.getName().replace('.', '/').concat(".class");
ZipEntry entry = new ZipEntry(path);
ByteBuffer b = Utils.toByteArray(c.getClassLoader().getResourceAsStream(path));
zipOut.putNextEntry(entry);
zipOut.write(b.array(), b.arrayOffset(), b.limit());
zipOut.closeEntry();
}
}
return bos.getByteBuffer();
}

@Before
public void before() throws Exception {
Path tmpSolrHome = createTempDir();
Expand Down Expand Up @@ -152,7 +121,7 @@ public void testProperty() throws Exception {
RestTestHarness harness = restTestHarness;
MapWriter confMap = getRespMap("/config", harness);
assertNotNull(confMap._get(asList("config", "requestHandler", "/admin/luke"), null));
assertNotNull(confMap._get(asList("config", "requestHandler", "/admin/system"), null));
assertNotNull(confMap._get(asList("config", "requestHandler", "/admin/info"), null));
assertNotNull(confMap._get(asList("config", "requestHandler", "/admin/file"), null));
assertNotNull(confMap._get(asList("config", "requestHandler", "/admin/ping"), null));

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

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

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

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

runConfigCommand(restTestHarness, "/config", payload);
restTestHarness.setServerProvider(() -> getBaseUrl());
restTestHarness.setServerProvider(RestTestBase::getBaseUrl);

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