You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@solr.apache.org by no...@apache.org on 2022/11/16 02:07:14 UTC
[solr] 01/01: refactor QueryResponseWriters
This is an automated email from the ASF dual-hosted git repository.
noble pushed a commit to branch jira/solr16547
in repository https://gitbox.apache.org/repos/asf/solr.git
commit 2d07feac9a48be3690bbbc75f08574a5947e39bb
Author: Noble Paul <no...@gmail.com>
AuthorDate: Wed Nov 16 13:06:50 2022 +1100
refactor QueryResponseWriters
---
.../java/org/apache/solr/core/CoreContainer.java | 4 +-
.../src/java/org/apache/solr/core/PluginBag.java | 141 ++++-----------------
.../org/apache/solr/core/RequestHandlerBag.java | 125 ++++++++++++++++++
.../java/org/apache/solr/core/RequestHandlers.java | 6 +-
.../java/org/apache/solr/core/ResponseWriters.java | 117 +++++++++++++++++
.../src/java/org/apache/solr/core/SolrCore.java | 73 +----------
.../org/apache/solr/filestore/PackageStoreAPI.java | 4 +-
.../java/org/apache/solr/handler/BlobHandler.java | 33 +++--
.../java/org/apache/solr/handler/ClusterAPI.java | 10 ++
.../apache/solr/handler/ReplicationHandler.java | 9 +-
.../apache/solr/handler/export/ExportWriter.java | 3 +-
.../org/apache/solr/jersey/JerseyApplications.java | 9 +-
.../org/apache/solr/jersey/MetricBeanFactory.java | 14 +-
.../apache/solr/jersey/RequestMetricHandling.java | 7 +-
.../java/org/apache/solr/servlet/HttpSolrCall.java | 6 +-
.../processor/UpdateRequestProcessorChain.java | 2 +-
.../src/test/org/apache/solr/OutputWriterTest.java | 4 +-
.../test/org/apache/solr/core/PluginBagTest.java | 20 +--
.../org/apache/solr/core/RequestHandlersTest.java | 2 +-
19 files changed, 342 insertions(+), 247 deletions(-)
diff --git a/solr/core/src/java/org/apache/solr/core/CoreContainer.java b/solr/core/src/java/org/apache/solr/core/CoreContainer.java
index 00eb7454b8d..e47475103b0 100644
--- a/solr/core/src/java/org/apache/solr/core/CoreContainer.java
+++ b/solr/core/src/java/org/apache/solr/core/CoreContainer.java
@@ -187,8 +187,8 @@ public class CoreContainer {
}
}
- private volatile PluginBag<SolrRequestHandler> containerHandlers =
- new PluginBag<>(SolrRequestHandler.class, null);
+ private volatile RequestHandlerBag containerHandlers =
+ new RequestHandlerBag( null);
private volatile ApplicationHandler jerseyAppHandler;
diff --git a/solr/core/src/java/org/apache/solr/core/PluginBag.java b/solr/core/src/java/org/apache/solr/core/PluginBag.java
index 5ecf681ad62..2cbc1a13a3f 100644
--- a/solr/core/src/java/org/apache/solr/core/PluginBag.java
+++ b/solr/core/src/java/org/apache/solr/core/PluginBag.java
@@ -16,9 +16,6 @@
*/
package org.apache.solr.core;
-import static java.util.Collections.singletonMap;
-import static org.apache.solr.api.ApiBag.HANDLER_NAME;
-
import java.io.IOException;
import java.lang.invoke.MethodHandles;
import java.util.Collection;
@@ -32,24 +29,17 @@ import java.util.Set;
import java.util.concurrent.ConcurrentHashMap;
import java.util.function.Supplier;
import java.util.stream.Collectors;
-import org.apache.commons.collections4.CollectionUtils;
+
import org.apache.lucene.util.ResourceLoader;
import org.apache.lucene.util.ResourceLoaderAware;
-import org.apache.solr.api.Api;
-import org.apache.solr.api.ApiBag;
-import org.apache.solr.api.ApiSupport;
-import org.apache.solr.api.JerseyResource;
import org.apache.solr.common.SolrException;
-import org.apache.solr.common.util.StrUtils;
import org.apache.solr.handler.RequestHandlerBase;
import org.apache.solr.handler.component.SearchComponent;
-import org.apache.solr.jersey.JerseyApplications;
import org.apache.solr.pkg.PackagePluginHolder;
import org.apache.solr.request.SolrRequestHandler;
import org.apache.solr.util.plugin.NamedListInitializedPlugin;
import org.apache.solr.util.plugin.PluginInfoInitialized;
import org.apache.solr.util.plugin.SolrCoreAware;
-import org.glassfish.jersey.server.ResourceConfig;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
@@ -57,34 +47,16 @@ import org.slf4j.LoggerFactory;
public class PluginBag<T> implements AutoCloseable {
private static final Logger log = LoggerFactory.getLogger(MethodHandles.lookup().lookupClass());
- private final Map<String, PluginHolder<T>> registry;
- private final Map<String, PluginHolder<T>> immutableRegistry;
+ protected Map<String, PluginHolder<T>> registry;
private String def;
private final Class<T> klass;
- private SolrCore core;
+ protected SolrCore core;
private final SolrConfig.SolrPluginInfo meta;
- private final ApiBag apiBag;
- private final ResourceConfig jerseyResources;
- public static class JerseyMetricsLookupRegistry
- extends HashMap<Class<? extends JerseyResource>, RequestHandlerBase> {}
-
- private final JerseyMetricsLookupRegistry infoBeanByResource;
+ private Map<String, PluginHolder<T>> defaults;
/** Pass needThreadSafety=true if plugins can be added and removed concurrently with lookups. */
public PluginBag(Class<T> klass, SolrCore core, boolean needThreadSafety) {
- if (klass == SolrRequestHandler.class) {
- this.apiBag = new ApiBag(core != null);
- this.infoBeanByResource = new JerseyMetricsLookupRegistry();
- this.jerseyResources =
- (core == null)
- ? new JerseyApplications.CoreContainerApp(infoBeanByResource)
- : new JerseyApplications.SolrCoreApp(core, infoBeanByResource);
- } else {
- this.apiBag = null;
- this.jerseyResources = null;
- this.infoBeanByResource = null;
- }
this.core = core;
this.klass = klass;
// TODO: since reads will dominate writes, we could also think about creating a new instance of
@@ -93,7 +65,6 @@ public class PluginBag<T> implements AutoCloseable {
// We could also perhaps make this constructor into a factory method to return different
// implementations depending on thread safety needs.
this.registry = needThreadSafety ? new ConcurrentHashMap<>() : new HashMap<>();
- this.immutableRegistry = Collections.unmodifiableMap(registry);
meta = SolrConfig.classVsSolrPluginInfo.get(klass.getName());
if (meta == null) {
throw new SolrException(
@@ -101,6 +72,15 @@ public class PluginBag<T> implements AutoCloseable {
}
}
+ public PluginBag(Class<T> klass, SolrCore core, boolean needThreadSafety, Map<String,
+ PluginHolder<T>> defaults,SolrConfig.SolrPluginInfo pluginMetaData) {
+ this.core = core;
+ this.klass = klass;
+ this.registry = needThreadSafety ? new ConcurrentHashMap<>(0) : new HashMap<>(0);
+ this.meta = pluginMetaData;
+ this.defaults = defaults;
+ }
+
/** Constructs a non-threadsafe plugin registry */
public PluginBag(Class<T> klass, SolrCore core) {
this(klass, core, false);
@@ -177,9 +157,14 @@ public class PluginBag<T> implements AutoCloseable {
/** Get a plugin by name. If the plugin is not already instantiated, it is done here */
public T get(String name) {
PluginHolder<T> result = registry.get(name);
+ if(result == null && defaults != null) result = defaults.get(name);
return result == null ? null : result.get();
}
+ public PluginHolder<T> getHolder(String name) {
+ return registry.get(name);
+ }
+
/**
* Fetches a plugin by name , or the default
*
@@ -193,7 +178,7 @@ public class PluginBag<T> implements AutoCloseable {
}
public Set<String> keySet() {
- return immutableRegistry.keySet();
+ return registry.keySet();
}
/** register a plugin by a name */
@@ -207,61 +192,8 @@ public class PluginBag<T> implements AutoCloseable {
@SuppressWarnings({"unchecked"})
public PluginHolder<T> put(String name, PluginHolder<T> plugin) {
- Boolean registerApi = null;
- Boolean disableHandler = null;
- if (plugin.pluginInfo != null) {
- String registerAt = plugin.pluginInfo.attributes.get("registerPath");
- if (registerAt != null) {
- List<String> strs = StrUtils.splitSmart(registerAt, ',');
- disableHandler = !strs.contains("/solr");
- registerApi = strs.contains("/v2");
- }
- }
-
- if (apiBag != null) {
- if (plugin.isLoaded()) {
- T inst = plugin.get();
- if (inst instanceof ApiSupport) {
- ApiSupport apiSupport = (ApiSupport) inst;
- if (registerApi == null) registerApi = apiSupport.registerV2();
- if (disableHandler == null) disableHandler = !apiSupport.registerV1();
-
- if (registerApi) {
- Collection<Api> apis = apiSupport.getApis();
- if (apis != null) {
- Map<String, String> nameSubstitutes = singletonMap(HANDLER_NAME, name);
- for (Api api : apis) {
- apiBag.register(api, nameSubstitutes);
- }
- }
-
- // TODO Should we use <requestHandler name="/blah"> to override the path that each
- // resource registers under?
- Collection<Class<? extends JerseyResource>> jerseyApis =
- apiSupport.getJerseyResources();
- if (!CollectionUtils.isEmpty(jerseyApis)) {
- for (Class<? extends JerseyResource> jerseyClazz : jerseyApis) {
- if (log.isDebugEnabled()) {
- log.debug("Registering jersey resource class: {}", jerseyClazz.getName());
- }
- jerseyResources.register(jerseyClazz);
- // See MetricsBeanFactory javadocs for a better understanding of this resource->RH
- // mapping
- if (inst instanceof RequestHandlerBase) {
- infoBeanByResource.put(jerseyClazz, (RequestHandlerBase) inst);
- }
- }
- }
- }
- }
- } else {
- if (registerApi != null && registerApi)
- apiBag.registerLazy((PluginHolder<SolrRequestHandler>) plugin, plugin.pluginInfo);
- }
- }
- if (disableHandler == null) disableHandler = Boolean.FALSE;
PluginHolder<T> old = null;
- if (!disableHandler) old = registry.put(name, plugin);
+ old = registry.put(name, plugin);
if (plugin.pluginInfo != null && plugin.pluginInfo.isDefault()) setDefault(name);
if (plugin.isLoaded()) registerMBean(plugin.get(), core, name);
// old instance has been replaced - close it to prevent mem leaks
@@ -279,10 +211,6 @@ public class PluginBag<T> implements AutoCloseable {
this.def = def;
}
- public Map<String, PluginHolder<T>> getRegistry() {
- return immutableRegistry;
- }
-
public boolean contains(String name) {
return registry.containsKey(name);
}
@@ -327,9 +255,11 @@ public class PluginBag<T> implements AutoCloseable {
infos.stream().map(i -> i.name).collect(Collectors.toList()));
}
}
- for (Map.Entry<String, T> e : defaults.entrySet()) {
- if (!contains(e.getKey())) {
- put(e.getKey(), new PluginHolder<>(null, e.getValue()));
+ if(defaults != null) {
+ for (Map.Entry<String, T> e : defaults.entrySet()) {
+ if (!contains(e.getKey())) {
+ put(e.getKey(), new PluginHolder<>(null, e.getValue()));
+ }
}
}
}
@@ -341,7 +271,7 @@ public class PluginBag<T> implements AutoCloseable {
return result.isLoaded();
}
- private void registerMBean(Object inst, SolrCore core, String pluginKey) {
+ protected void registerMBean(Object inst, SolrCore core, String pluginKey) {
if (core == null) return;
if (inst instanceof SolrInfoBean) {
SolrInfoBean mBean = (SolrInfoBean) inst;
@@ -398,7 +328,6 @@ public class PluginBag<T> implements AutoCloseable {
return Optional.ofNullable(inst);
}
- @Override
public T get() {
return inst;
}
@@ -436,7 +365,6 @@ public class PluginBag<T> implements AutoCloseable {
return pluginInfo;
}
- @Override
public String toString() {
return String.valueOf(inst);
}
@@ -518,21 +446,4 @@ public class PluginBag<T> implements AutoCloseable {
return true;
}
}
-
- public Api v2lookup(String path, String method, Map<String, String> parts) {
- if (apiBag == null) {
- throw new SolrException(
- SolrException.ErrorCode.SERVER_ERROR,
- "this should not happen, looking up for v2 API at the wrong place");
- }
- return apiBag.lookup(path, method, parts);
- }
-
- public ApiBag getApiBag() {
- return apiBag;
- }
-
- public ResourceConfig getJerseyEndpoints() {
- return jerseyResources;
- }
}
diff --git a/solr/core/src/java/org/apache/solr/core/RequestHandlerBag.java b/solr/core/src/java/org/apache/solr/core/RequestHandlerBag.java
new file mode 100644
index 00000000000..cfddb08e4a7
--- /dev/null
+++ b/solr/core/src/java/org/apache/solr/core/RequestHandlerBag.java
@@ -0,0 +1,125 @@
+package org.apache.solr.core;
+
+
+import org.apache.commons.collections4.CollectionUtils;
+import org.apache.solr.api.Api;
+import org.apache.solr.api.ApiBag;
+import org.apache.solr.api.ApiSupport;
+import org.apache.solr.api.JerseyResource;
+import org.apache.solr.common.SolrException;
+import org.apache.solr.common.util.StrUtils;
+import org.apache.solr.handler.RequestHandlerBase;
+import org.apache.solr.request.SolrRequestHandler;
+import org.glassfish.jersey.server.ResourceConfig;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import java.lang.invoke.MethodHandles;
+import java.util.Collection;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+import static java.util.Collections.singletonMap;
+import static org.apache.solr.api.ApiBag.HANDLER_NAME;
+
+public class RequestHandlerBag extends PluginBag<SolrRequestHandler> {
+ private static final Logger log = LoggerFactory.getLogger(MethodHandles.lookup().lookupClass());
+
+ private ApiBag apiBag;
+ private ResourceConfig jerseyResources;
+ private JerseyMetricsLookupRegistry infoBeanByResource;
+
+ public RequestHandlerBag(SolrCore core) {
+ super(SolrRequestHandler.class, core, true);
+ this.apiBag = new ApiBag(core != null);
+ }
+
+ @Override
+ public PluginHolder<SolrRequestHandler> put(String name, PluginHolder<SolrRequestHandler> plugin) {
+ Boolean registerApi = null;
+ Boolean disableHandler = null;
+ if (plugin.pluginInfo != null) {
+ String registerAt = plugin.pluginInfo.attributes.get("registerPath");
+ if (registerAt != null) {
+ List<String> strs = StrUtils.splitSmart(registerAt, ',');
+ disableHandler = !strs.contains("/solr");
+ registerApi = strs.contains("/v2");
+ }
+ }
+
+ if (apiBag != null) {
+ if (plugin.isLoaded()) {
+ SolrRequestHandler inst = plugin.get();
+ if (inst instanceof ApiSupport) {
+ ApiSupport apiSupport = (ApiSupport) inst;
+ if (registerApi == null) registerApi = apiSupport.registerV2();
+ if (disableHandler == null) disableHandler = !apiSupport.registerV1();
+
+ if (registerApi) {
+ Collection<Api> apis = apiSupport.getApis();
+ if (apis != null) {
+ Map<String, String> nameSubstitutes = singletonMap(HANDLER_NAME, name);
+ for (Api api : apis) {
+ apiBag.register(api, nameSubstitutes);
+ }
+ }
+
+ // TODO Should we use <requestHandler name="/blah"> to override the path that each
+ // resource registers under?
+ Collection<Class<? extends JerseyResource>> jerseyApis =
+ apiSupport.getJerseyResources();
+ if (!CollectionUtils.isEmpty(jerseyApis)) {
+ for (Class<? extends JerseyResource> jerseyClazz : jerseyApis) {
+ if (log.isDebugEnabled()) {
+ log.debug("Registering jersey resource class: {}", jerseyClazz.getName());
+ }
+ jerseyResources.register(jerseyClazz);
+ // See MetricsBeanFactory javadocs for a better understanding of this resource->RH
+ // mapping
+ if (inst instanceof RequestHandlerBase) {
+ infoBeanByResource.put(jerseyClazz, (RequestHandlerBase) inst);
+ }
+ }
+ }
+ }
+ }
+ } else {
+ if (registerApi != null && registerApi)
+ apiBag.registerLazy((PluginHolder<SolrRequestHandler>) plugin, plugin.pluginInfo);
+ }
+ }
+ PluginHolder<SolrRequestHandler> old = null;
+ if (disableHandler == null) disableHandler = Boolean.FALSE;
+ if (!disableHandler) old = registry.put(name, plugin);
+ if (plugin.pluginInfo != null && plugin.pluginInfo.isDefault()) setDefault(name);
+ if (plugin.isLoaded()) registerMBean(plugin.get(), core, name);
+ // old instance has been replaced - close it to prevent mem leaks
+ if (old != null && old != plugin) {
+ closeQuietly(old);
+ }
+ return old;
+ }
+
+ public Api v2lookup(String path, String method, Map<String, String> parts) {
+ if (apiBag == null) {
+ throw new SolrException(
+ SolrException.ErrorCode.SERVER_ERROR,
+ "this should not happen, looking up for v2 API at the wrong place");
+ }
+ return apiBag.lookup(path, method, parts);
+ }
+
+
+
+ public ApiBag getApiBag() {
+ return apiBag;
+ }
+
+ public ResourceConfig getJerseyEndpoints() {
+ return jerseyResources;
+ }
+
+ public static class JerseyMetricsLookupRegistry
+ extends HashMap<Class<? extends JerseyResource>, RequestHandlerBase> {}
+}
diff --git a/solr/core/src/java/org/apache/solr/core/RequestHandlers.java b/solr/core/src/java/org/apache/solr/core/RequestHandlers.java
index dca7c832e3f..4c2e7d15041 100644
--- a/solr/core/src/java/org/apache/solr/core/RequestHandlers.java
+++ b/solr/core/src/java/org/apache/solr/core/RequestHandlers.java
@@ -33,7 +33,7 @@ public final class RequestHandlers {
private final SolrCore core;
- final PluginBag<SolrRequestHandler> handlers;
+ final RequestHandlerBag handlers;
/**
* Trim the trailing '/' if it's there, and convert null to empty string.
@@ -51,7 +51,7 @@ public final class RequestHandlers {
this.core = core;
// we need a thread safe registry since methods like register are currently documented to be
// thread safe.
- handlers = new PluginBag<>(SolrRequestHandler.class, core, true);
+ handlers = new RequestHandlerBag( core);
}
/**
@@ -79,7 +79,7 @@ public final class RequestHandlers {
}
/** Returns an unmodifiable Map containing the registered handlers */
- public PluginBag<SolrRequestHandler> getRequestHandlers() {
+ public RequestHandlerBag getRequestHandlers() {
return handlers;
}
diff --git a/solr/core/src/java/org/apache/solr/core/ResponseWriters.java b/solr/core/src/java/org/apache/solr/core/ResponseWriters.java
new file mode 100644
index 00000000000..8a11bb3390f
--- /dev/null
+++ b/solr/core/src/java/org/apache/solr/core/ResponseWriters.java
@@ -0,0 +1,117 @@
+/*
+ * 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.core;
+
+import com.google.common.collect.ImmutableMap;
+import org.apache.solr.client.solrj.impl.BinaryResponseParser;
+import org.apache.solr.common.params.CommonParams;
+import org.apache.solr.handler.ReplicationHandler;
+import org.apache.solr.request.SolrQueryRequest;
+import org.apache.solr.response.*;
+
+import java.io.Closeable;
+import java.io.IOException;
+import java.io.OutputStream;
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.Map;
+
+public class ResponseWriters {
+ public static final SolrConfig.SolrPluginInfo info = SolrConfig.classVsSolrPluginInfo.get(QueryResponseWriter.class.getName());
+ private static QueryResponseWriter standard;
+
+ public static QueryResponseWriter get(String name) {
+ return DEFAULT_RESPONSE_WRITERS.get(name);
+ }
+ public static QueryResponseWriter getOrDefault(String name){
+ QueryResponseWriter result = DEFAULT_RESPONSE_WRITERS.get(name);
+ return result==null? standard: result;
+
+ }
+
+ public static final Map<String, QueryResponseWriter> DEFAULT_RESPONSE_WRITERS;
+ public static final Map<String, PluginBag.PluginHolder<QueryResponseWriter>> DEFAULT_RESPONSE_WRITER_HOLDERS ;
+
+
+ static {
+ HashMap<String, QueryResponseWriter> m = new HashMap<>(15, 1);
+ m.put("xml", new XMLResponseWriter());
+ m.put(CommonParams.JSON, new JSONResponseWriter());
+ m.put("standard", m.get(CommonParams.JSON));
+ m.put("geojson", new GeoJSONResponseWriter());
+ m.put("graphml", new GraphMLResponseWriter());
+ m.put("python", new PythonResponseWriter());
+ m.put("php", new PHPResponseWriter());
+ m.put("phps", new PHPSerializedResponseWriter());
+ m.put("ruby", new RubyResponseWriter());
+ m.put("raw", new RawResponseWriter());
+ m.put(CommonParams.JAVABIN, new BinaryResponseWriter());
+ m.put("csv", new CSVResponseWriter());
+ m.put("schema.xml", new SchemaXmlResponseWriter());
+ m.put("smile", new SmileResponseWriter());
+ standard = m.get("standard");
+ m.put(ReplicationHandler.FILE_STREAM, getFileStreamWriter());
+ DEFAULT_RESPONSE_WRITERS = Collections.unmodifiableMap(m);
+ try {
+ m.put(
+ "xlsx",
+ (QueryResponseWriter)
+ Class.forName("org.apache.solr.handler.extraction.XLSXResponseWriter")
+ .getConstructor()
+ .newInstance());
+ } catch (Exception e) {
+ // don't worry; extraction module not in class path
+ }
+ ImmutableMap.Builder<String, PluginBag.PluginHolder<QueryResponseWriter>> b = ImmutableMap.builder();
+ DEFAULT_RESPONSE_WRITERS.forEach((k, v) -> b.put(k, new PluginBag.PluginHolder<>(v, info)));
+ DEFAULT_RESPONSE_WRITER_HOLDERS = b.build();
+ }
+
+ private static BinaryResponseWriter getFileStreamWriter() {
+ return new BinaryResponseWriter() {
+ @Override
+ public void write(OutputStream out, SolrQueryRequest req, SolrQueryResponse response)
+ throws IOException {
+ RawWriter rawWriter = (RawWriter) response.getValues().get(ReplicationHandler.FILE_STREAM);
+ if (rawWriter != null) {
+ rawWriter.write(out);
+ if (rawWriter instanceof Closeable) ((Closeable) rawWriter).close();
+ }
+ }
+
+ @Override
+ public String getContentType(SolrQueryRequest request, SolrQueryResponse response) {
+ RawWriter rawWriter = (RawWriter) response.getValues().get(ReplicationHandler.FILE_STREAM);
+ if (rawWriter != null) {
+ return rawWriter.getContentType();
+ } else {
+ return BinaryResponseParser.BINARY_CONTENT_TYPE;
+ }
+ }
+ };
+ }
+
+
+
+ public interface RawWriter {
+ default String getContentType() {
+ return BinaryResponseParser.BINARY_CONTENT_TYPE;
+ }
+
+ void write(OutputStream os) throws IOException;
+ }
+}
diff --git a/solr/core/src/java/org/apache/solr/core/SolrCore.java b/solr/core/src/java/org/apache/solr/core/SolrCore.java
index cf6e7d51cc9..8ff9255d221 100644
--- a/solr/core/src/java/org/apache/solr/core/SolrCore.java
+++ b/solr/core/src/java/org/apache/solr/core/SolrCore.java
@@ -17,6 +17,7 @@
package org.apache.solr.core;
import static org.apache.solr.common.params.CommonParams.PATH;
+import static org.apache.solr.core.ResponseWriters.DEFAULT_RESPONSE_WRITERS;
import com.codahale.metrics.Counter;
import com.codahale.metrics.Timer;
@@ -1997,7 +1998,7 @@ public class SolrCore implements SolrInfoBean, Closeable {
&& searchComponents.get(name) instanceof HighlightComponent) {
if (!HighlightComponent.COMPONENT_NAME.equals(name)) {
searchComponents.put(
- HighlightComponent.COMPONENT_NAME, searchComponents.getRegistry().get(name));
+ HighlightComponent.COMPONENT_NAME, searchComponents.getHolder(name));
}
break;
}
@@ -2991,84 +2992,20 @@ public class SolrCore implements SolrInfoBean, Closeable {
public PluginBag<QueryResponseWriter> getResponseWriters() {
return responseWriters;
}
-
private final PluginBag<QueryResponseWriter> responseWriters =
- new PluginBag<>(QueryResponseWriter.class, this);
- public static final Map<String, QueryResponseWriter> DEFAULT_RESPONSE_WRITERS;
-
- static {
- HashMap<String, QueryResponseWriter> m = new HashMap<>(15, 1);
- m.put("xml", new XMLResponseWriter());
- m.put(CommonParams.JSON, new JSONResponseWriter());
- m.put("standard", m.get(CommonParams.JSON));
- m.put("geojson", new GeoJSONResponseWriter());
- m.put("graphml", new GraphMLResponseWriter());
- m.put("python", new PythonResponseWriter());
- m.put("php", new PHPResponseWriter());
- m.put("phps", new PHPSerializedResponseWriter());
- m.put("ruby", new RubyResponseWriter());
- m.put("raw", new RawResponseWriter());
- m.put(CommonParams.JAVABIN, new BinaryResponseWriter());
- m.put("csv", new CSVResponseWriter());
- m.put("schema.xml", new SchemaXmlResponseWriter());
- m.put("smile", new SmileResponseWriter());
- m.put(ReplicationHandler.FILE_STREAM, getFileStreamWriter());
- DEFAULT_RESPONSE_WRITERS = Collections.unmodifiableMap(m);
- try {
- m.put(
- "xlsx",
- (QueryResponseWriter)
- Class.forName("org.apache.solr.handler.extraction.XLSXResponseWriter")
- .getConstructor()
- .newInstance());
- } catch (Exception e) {
- // don't worry; extraction module not in class path
- }
- }
-
- private static BinaryResponseWriter getFileStreamWriter() {
- return new BinaryResponseWriter() {
- @Override
- public void write(OutputStream out, SolrQueryRequest req, SolrQueryResponse response)
- throws IOException {
- RawWriter rawWriter = (RawWriter) response.getValues().get(ReplicationHandler.FILE_STREAM);
- if (rawWriter != null) {
- rawWriter.write(out);
- if (rawWriter instanceof Closeable) ((Closeable) rawWriter).close();
- }
- }
-
- @Override
- public String getContentType(SolrQueryRequest request, SolrQueryResponse response) {
- RawWriter rawWriter = (RawWriter) response.getValues().get(ReplicationHandler.FILE_STREAM);
- if (rawWriter != null) {
- return rawWriter.getContentType();
- } else {
- return BinaryResponseParser.BINARY_CONTENT_TYPE;
- }
- }
- };
- }
-
+ new PluginBag<>(QueryResponseWriter.class, this, false,
+ ResponseWriters.DEFAULT_RESPONSE_WRITER_HOLDERS, ResponseWriters.info);
public void fetchLatestSchema() {
IndexSchema schema = configSet.getIndexSchema(true);
setLatestSchema(schema);
}
- public interface RawWriter {
- default String getContentType() {
- return BinaryResponseParser.BINARY_CONTENT_TYPE;
- }
-
- void write(OutputStream os) throws IOException;
- }
-
/**
* Configure the query response writers. There will always be a default writer; additional writers
* may also be configured.
*/
private void initWriters() {
- responseWriters.init(DEFAULT_RESPONSE_WRITERS, this);
+ responseWriters.init(null, this);
// configure the default response writer; this one should never be null
if (responseWriters.getDefault() == null) responseWriters.setDefault("standard");
}
diff --git a/solr/core/src/java/org/apache/solr/filestore/PackageStoreAPI.java b/solr/core/src/java/org/apache/solr/filestore/PackageStoreAPI.java
index 0a98bba9a2f..d5985e06f2c 100644
--- a/solr/core/src/java/org/apache/solr/filestore/PackageStoreAPI.java
+++ b/solr/core/src/java/org/apache/solr/filestore/PackageStoreAPI.java
@@ -46,7 +46,7 @@ import org.apache.solr.common.util.StrUtils;
import org.apache.solr.common.util.Utils;
import org.apache.solr.core.BlobRepository;
import org.apache.solr.core.CoreContainer;
-import org.apache.solr.core.SolrCore;
+import org.apache.solr.core.ResponseWriters;
import org.apache.solr.pkg.PackageAPI;
import org.apache.solr.request.SolrQueryRequest;
import org.apache.solr.response.SolrQueryResponse;
@@ -348,7 +348,7 @@ public class PackageStoreAPI {
req.setParams(SolrParams.wrapDefaults(solrParams, req.getParams()));
rsp.add(
FILE_STREAM,
- (SolrCore.RawWriter)
+ (ResponseWriters.RawWriter)
os ->
packageStore.get(
path,
diff --git a/solr/core/src/java/org/apache/solr/handler/BlobHandler.java b/solr/core/src/java/org/apache/solr/handler/BlobHandler.java
index 3bb14b19ed4..789be7117be 100644
--- a/solr/core/src/java/org/apache/solr/handler/BlobHandler.java
+++ b/solr/core/src/java/org/apache/solr/handler/BlobHandler.java
@@ -53,6 +53,7 @@ import org.apache.solr.common.util.ContentStream;
import org.apache.solr.common.util.NamedList;
import org.apache.solr.common.util.StrUtils;
import org.apache.solr.core.PluginInfo;
+import org.apache.solr.core.ResponseWriters;
import org.apache.solr.core.SolrCore;
import org.apache.solr.handler.admin.api.GetBlobInfoAPI;
import org.apache.solr.handler.admin.api.UploadBlobAPI;
@@ -210,24 +211,20 @@ public class BlobHandler extends RequestHandlerBase
if (docs.totalHits.value > 0) {
rsp.add(
ReplicationHandler.FILE_STREAM,
- new SolrCore.RawWriter() {
-
- @Override
- public void write(OutputStream os) throws IOException {
- Document doc = req.getSearcher().doc(docs.scoreDocs[0].doc);
- IndexableField sf = doc.getField("blob");
- FieldType fieldType = req.getSchema().getField("blob").getType();
- ByteBuffer buf = (ByteBuffer) fieldType.toObject(sf);
- if (buf == null) {
- // should never happen unless a user wrote this document directly
- throw new SolrException(
- SolrException.ErrorCode.NOT_FOUND,
- "Invalid document . No field called blob");
- } else {
- os.write(buf.array(), buf.arrayOffset(), buf.limit());
- }
- }
- });
+ (ResponseWriters.RawWriter) os -> {
+ Document doc = req.getSearcher().doc(docs.scoreDocs[0].doc);
+ IndexableField sf = doc.getField("blob");
+ FieldType fieldType = req.getSchema().getField("blob").getType();
+ ByteBuffer buf = (ByteBuffer) fieldType.toObject(sf);
+ if (buf == null) {
+ // should never happen unless a user wrote this document directly
+ throw new SolrException(
+ SolrException.ErrorCode.NOT_FOUND,
+ "Invalid document . No field called blob");
+ } else {
+ os.write(buf.array(), buf.arrayOffset(), buf.limit());
+ }
+ });
} else {
throw new SolrException(
diff --git a/solr/core/src/java/org/apache/solr/handler/ClusterAPI.java b/solr/core/src/java/org/apache/solr/handler/ClusterAPI.java
index 1a56f7980d5..236159bbe0a 100644
--- a/solr/core/src/java/org/apache/solr/handler/ClusterAPI.java
+++ b/solr/core/src/java/org/apache/solr/handler/ClusterAPI.java
@@ -77,6 +77,16 @@ public class ClusterAPI {
this.configSetsHandler = configSetsHandler;
}
+ @EndPoint(method = GET, path = "/node/heap", permission = COLL_READ_PERM)
+ public void heap(SolrQueryRequest req, SolrQueryResponse rsp) throws Exception {
+ Runtime rt = Runtime.getRuntime();
+ if(req.getParams().getBool("gc", false)) {
+ rt.gc();
+ }
+ rsp.add("heap", rt.totalMemory() - rt.freeMemory());
+ }
+
+
@EndPoint(method = GET, path = "/cluster/node-roles", permission = COLL_READ_PERM)
public void roles(SolrQueryRequest req, SolrQueryResponse rsp) throws Exception {
rsp.add(
diff --git a/solr/core/src/java/org/apache/solr/handler/ReplicationHandler.java b/solr/core/src/java/org/apache/solr/handler/ReplicationHandler.java
index 7cae4115598..29b0e47aaa7 100644
--- a/solr/core/src/java/org/apache/solr/handler/ReplicationHandler.java
+++ b/solr/core/src/java/org/apache/solr/handler/ReplicationHandler.java
@@ -83,13 +83,8 @@ import org.apache.solr.common.util.SimpleOrderedMap;
import org.apache.solr.common.util.SolrNamedThreadFactory;
import org.apache.solr.common.util.StrUtils;
import org.apache.solr.common.util.SuppressForbidden;
-import org.apache.solr.core.CloseHook;
-import org.apache.solr.core.CoreContainer;
+import org.apache.solr.core.*;
import org.apache.solr.core.DirectoryFactory.DirContext;
-import org.apache.solr.core.IndexDeletionPolicyWrapper;
-import org.apache.solr.core.SolrCore;
-import org.apache.solr.core.SolrDeletionPolicy;
-import org.apache.solr.core.SolrEventListener;
import org.apache.solr.core.backup.repository.BackupRepository;
import org.apache.solr.core.backup.repository.LocalFileSystemRepository;
import org.apache.solr.handler.IndexFetcher.IndexFetchResult;
@@ -1582,7 +1577,7 @@ public class ReplicationHandler extends RequestHandlerBase implements SolrCoreAw
}
/** This class is used to read and send files in the lucene index */
- private class DirectoryFileStream implements SolrCore.RawWriter {
+ private class DirectoryFileStream implements ResponseWriters.RawWriter {
protected SolrParams params;
protected FastOutputStream fos;
diff --git a/solr/core/src/java/org/apache/solr/handler/export/ExportWriter.java b/solr/core/src/java/org/apache/solr/handler/export/ExportWriter.java
index cc1599562a3..d3764c1088b 100644
--- a/solr/core/src/java/org/apache/solr/handler/export/ExportWriter.java
+++ b/solr/core/src/java/org/apache/solr/handler/export/ExportWriter.java
@@ -55,6 +55,7 @@ import org.apache.solr.common.params.CommonParams;
import org.apache.solr.common.params.SolrParams;
import org.apache.solr.common.params.StreamParams;
import org.apache.solr.common.util.JavaBinCodec;
+import org.apache.solr.core.ResponseWriters;
import org.apache.solr.core.SolrCore;
import org.apache.solr.metrics.SolrMetricsContext;
import org.apache.solr.request.SolrQueryRequest;
@@ -91,7 +92,7 @@ import org.slf4j.LoggerFactory;
* across the wire) and marked as sent (unset in the bitmap). This process repeats until all
* matching documents have been sent.
*/
-public class ExportWriter implements SolrCore.RawWriter, Closeable {
+public class ExportWriter implements ResponseWriters.RawWriter, Closeable {
private static final Logger log = LoggerFactory.getLogger(MethodHandles.lookup().lookupClass());
public static final String BATCH_SIZE_PARAM = "batchSize";
diff --git a/solr/core/src/java/org/apache/solr/jersey/JerseyApplications.java b/solr/core/src/java/org/apache/solr/jersey/JerseyApplications.java
index 7a4bb484e4b..dc613dbe958 100644
--- a/solr/core/src/java/org/apache/solr/jersey/JerseyApplications.java
+++ b/solr/core/src/java/org/apache/solr/jersey/JerseyApplications.java
@@ -21,7 +21,8 @@ import io.swagger.v3.oas.annotations.OpenAPIDefinition;
import io.swagger.v3.oas.annotations.info.Info;
import io.swagger.v3.oas.annotations.info.License;
import javax.inject.Singleton;
-import org.apache.solr.core.PluginBag;
+
+import org.apache.solr.core.RequestHandlerBag;
import org.apache.solr.core.SolrCore;
import org.apache.solr.request.SolrQueryRequest;
import org.apache.solr.response.SolrQueryResponse;
@@ -44,7 +45,7 @@ import org.glassfish.jersey.server.ResourceConfig;
public class JerseyApplications {
public static class CoreContainerApp extends ResourceConfig {
- public CoreContainerApp(PluginBag.JerseyMetricsLookupRegistry beanRegistry) {
+ public CoreContainerApp(RequestHandlerBag.JerseyMetricsLookupRegistry beanRegistry) {
super();
// Authentication and authorization
@@ -68,7 +69,7 @@ public class JerseyApplications {
@Override
protected void configure() {
bindFactory(new MetricBeanFactory(beanRegistry))
- .to(PluginBag.JerseyMetricsLookupRegistry.class)
+ .to(RequestHandlerBag.JerseyMetricsLookupRegistry.class)
.in(Singleton.class);
}
});
@@ -102,7 +103,7 @@ public class JerseyApplications {
public static class SolrCoreApp extends CoreContainerApp {
- public SolrCoreApp(SolrCore solrCore, PluginBag.JerseyMetricsLookupRegistry beanRegistry) {
+ public SolrCoreApp(SolrCore solrCore, RequestHandlerBag.JerseyMetricsLookupRegistry beanRegistry) {
super(beanRegistry);
// Dependency Injection for Jersey resources
diff --git a/solr/core/src/java/org/apache/solr/jersey/MetricBeanFactory.java b/solr/core/src/java/org/apache/solr/jersey/MetricBeanFactory.java
index c23851359d9..9821cd51f87 100644
--- a/solr/core/src/java/org/apache/solr/jersey/MetricBeanFactory.java
+++ b/solr/core/src/java/org/apache/solr/jersey/MetricBeanFactory.java
@@ -17,7 +17,7 @@
package org.apache.solr.jersey;
-import org.apache.solr.core.PluginBag;
+import org.apache.solr.core.RequestHandlerBag;
import org.glassfish.hk2.api.Factory;
/**
@@ -26,7 +26,7 @@ import org.glassfish.hk2.api.Factory;
* <p>Currently, Jersey resources that have a corresponding v1 API produce the same metrics as their
* v1 equivalent and rely on the v1 requestHandler instance to do so. Solr facilitates this by
* building a map of the Jersey resource to requestHandler mapping (a {@link
- * org.apache.solr.core.PluginBag.JerseyMetricsLookupRegistry}), and injecting it into the pre- and
+ * RequestHandlerBag.JerseyMetricsLookupRegistry}), and injecting it into the pre- and
* post- Jersey filters that handle metrics.
*
* <p>This isn't ideal, as requestHandler's don't really "fit" conceptually here. But it's
@@ -35,21 +35,21 @@ import org.glassfish.hk2.api.Factory;
* @see RequestMetricHandling.PreRequestMetricsFilter
* @see RequestMetricHandling.PostRequestMetricsFilter
*/
-public class MetricBeanFactory implements Factory<PluginBag.JerseyMetricsLookupRegistry> {
+public class MetricBeanFactory implements Factory<RequestHandlerBag.JerseyMetricsLookupRegistry> {
- private final PluginBag.JerseyMetricsLookupRegistry metricsLookupRegistry;
+ private final RequestHandlerBag.JerseyMetricsLookupRegistry metricsLookupRegistry;
- public MetricBeanFactory(PluginBag.JerseyMetricsLookupRegistry metricsLookupRegistry) {
+ public MetricBeanFactory(RequestHandlerBag.JerseyMetricsLookupRegistry metricsLookupRegistry) {
this.metricsLookupRegistry = metricsLookupRegistry;
}
@Override
- public PluginBag.JerseyMetricsLookupRegistry provide() {
+ public RequestHandlerBag.JerseyMetricsLookupRegistry provide() {
return metricsLookupRegistry;
}
@Override
- public void dispose(PluginBag.JerseyMetricsLookupRegistry instance) {
+ public void dispose(RequestHandlerBag.JerseyMetricsLookupRegistry instance) {
/* No-op */
}
}
diff --git a/solr/core/src/java/org/apache/solr/jersey/RequestMetricHandling.java b/solr/core/src/java/org/apache/solr/jersey/RequestMetricHandling.java
index 595027005ad..b4543a2084b 100644
--- a/solr/core/src/java/org/apache/solr/jersey/RequestMetricHandling.java
+++ b/solr/core/src/java/org/apache/solr/jersey/RequestMetricHandling.java
@@ -31,7 +31,8 @@ import javax.ws.rs.container.ContainerResponseContext;
import javax.ws.rs.container.ContainerResponseFilter;
import javax.ws.rs.container.ResourceInfo;
import javax.ws.rs.core.Context;
-import org.apache.solr.core.PluginBag;
+
+import org.apache.solr.core.RequestHandlerBag;
import org.apache.solr.handler.RequestHandlerBase;
import org.apache.solr.request.SolrQueryRequest;
import org.slf4j.Logger;
@@ -58,10 +59,10 @@ public class RequestMetricHandling {
@Context private ResourceInfo resourceInfo;
- private PluginBag.JerseyMetricsLookupRegistry beanRegistry;
+ private RequestHandlerBag.JerseyMetricsLookupRegistry beanRegistry;
@Inject
- public PreRequestMetricsFilter(PluginBag.JerseyMetricsLookupRegistry beanRegistry) {
+ public PreRequestMetricsFilter(RequestHandlerBag.JerseyMetricsLookupRegistry beanRegistry) {
this.beanRegistry = beanRegistry;
}
diff --git a/solr/core/src/java/org/apache/solr/servlet/HttpSolrCall.java b/solr/core/src/java/org/apache/solr/servlet/HttpSolrCall.java
index debd481a9a3..692dde2f8d6 100644
--- a/solr/core/src/java/org/apache/solr/servlet/HttpSolrCall.java
+++ b/solr/core/src/java/org/apache/solr/servlet/HttpSolrCall.java
@@ -101,6 +101,7 @@ import org.apache.solr.common.util.TimeSource;
import org.apache.solr.common.util.Utils;
import org.apache.solr.common.util.ValidatingJsonMap;
import org.apache.solr.core.CoreContainer;
+import org.apache.solr.core.ResponseWriters;
import org.apache.solr.core.SolrConfig;
import org.apache.solr.core.SolrCore;
import org.apache.solr.handler.ContentStreamHandlerBase;
@@ -876,7 +877,7 @@ public class HttpSolrCall {
}
}
QueryResponseWriter respWriter =
- SolrCore.DEFAULT_RESPONSE_WRITERS.get(solrReq.getParams().get(CommonParams.WT));
+ ResponseWriters.get(solrReq.getParams().get(CommonParams.WT));
if (respWriter == null) respWriter = getResponseWriter();
writeResponse(solrResp, respWriter, Method.getMethod(req.getMethod()));
if (shouldAudit()) {
@@ -905,8 +906,7 @@ public class HttpSolrCall {
if (core != null) {
return core.getQueryResponseWriter(wt);
} else {
- return SolrCore.DEFAULT_RESPONSE_WRITERS.getOrDefault(
- wt, SolrCore.DEFAULT_RESPONSE_WRITERS.get("standard"));
+ return ResponseWriters.getOrDefault(wt);
}
}
diff --git a/solr/core/src/java/org/apache/solr/update/processor/UpdateRequestProcessorChain.java b/solr/core/src/java/org/apache/solr/update/processor/UpdateRequestProcessorChain.java
index 1f5476632f8..e0bfc06c371 100644
--- a/solr/core/src/java/org/apache/solr/update/processor/UpdateRequestProcessorChain.java
+++ b/solr/core/src/java/org/apache/solr/update/processor/UpdateRequestProcessorChain.java
@@ -302,7 +302,7 @@ public final class UpdateRequestProcessorChain implements PluginInfoInitialized
if (s.isEmpty()) continue;
UpdateRequestProcessorFactory p = null;
PluginBag.PluginHolder<UpdateRequestProcessorFactory> holder =
- core.getUpdateProcessors().getRegistry().get(s);
+ core.getUpdateProcessors().getHolder(s);
if (holder instanceof PackagePluginHolder) {
p = new LazyUpdateRequestProcessorFactory(holder);
} else {
diff --git a/solr/core/src/test/org/apache/solr/OutputWriterTest.java b/solr/core/src/test/org/apache/solr/OutputWriterTest.java
index 13eb69d9014..471471b3e41 100644
--- a/solr/core/src/test/org/apache/solr/OutputWriterTest.java
+++ b/solr/core/src/test/org/apache/solr/OutputWriterTest.java
@@ -67,10 +67,10 @@ public class OutputWriterTest extends SolrTestCaseJ4 {
public void testLazy() {
PluginBag.PluginHolder<QueryResponseWriter> qrw =
- h.getCore().getResponseWriters().getRegistry().get("useless");
+ h.getCore().getResponseWriters().getHolder("useless");
assertTrue("Should be a lazy class", qrw instanceof PluginBag.LazyPluginHolder);
- qrw = h.getCore().getResponseWriters().getRegistry().get("xml");
+ qrw = h.getCore().getResponseWriters().getHolder("xml");
assertTrue("Should not be a lazy class", qrw.isLoaded());
assertSame("Should not be a lazy class", qrw.getClass(), PluginBag.PluginHolder.class);
}
diff --git a/solr/core/src/test/org/apache/solr/core/PluginBagTest.java b/solr/core/src/test/org/apache/solr/core/PluginBagTest.java
index f0281038197..c0a011bc67d 100644
--- a/solr/core/src/test/org/apache/solr/core/PluginBagTest.java
+++ b/solr/core/src/test/org/apache/solr/core/PluginBagTest.java
@@ -49,14 +49,14 @@ public class PluginBagTest extends SolrTestCaseJ4 {
@Test
public void testOnlyInitsJerseyIfHoldingRequestHandlers() {
- final PluginBag<SearchComponent> nonRequestHandlerBag =
- new PluginBag<>(SearchComponent.class, null);
+ final RequestHandlerBag nonRequestHandlerBag =
+ new RequestHandlerBag(null);
assertNull(
"Jersey app should not be created for plugin bags that aren't managing RequestHandler's",
nonRequestHandlerBag.getJerseyEndpoints());
- final PluginBag<SolrRequestHandler> handlerPluginBag =
- new PluginBag<>(SolrRequestHandler.class, null);
+ final RequestHandlerBag handlerPluginBag =
+ new RequestHandlerBag(null);
assertNotNull(
"Jersey app should be created for plugin bags that manage RequestHandlers",
handlerPluginBag.getJerseyEndpoints());
@@ -64,16 +64,16 @@ public class PluginBagTest extends SolrTestCaseJ4 {
@Test
public void testCreatesCoreSpecificJerseyAppIfCoreProvided() {
- final PluginBag<SolrRequestHandler> handlerPluginBag =
- new PluginBag<>(SolrRequestHandler.class, solrCore);
+ final RequestHandlerBag handlerPluginBag =
+ new RequestHandlerBag(solrCore);
assertEquals(
JerseyApplications.SolrCoreApp.class, handlerPluginBag.getJerseyEndpoints().getClass());
}
@Test
public void testCreatesContainerSpecificJerseyAppIfNoCoreProvided() {
- final PluginBag<SolrRequestHandler> handlerPluginBag =
- new PluginBag<>(SolrRequestHandler.class, null);
+ final RequestHandlerBag handlerPluginBag =
+ new RequestHandlerBag(null);
assertEquals(
JerseyApplications.CoreContainerApp.class,
handlerPluginBag.getJerseyEndpoints().getClass());
@@ -81,8 +81,8 @@ public class PluginBagTest extends SolrTestCaseJ4 {
@Test
public void testRegistersJerseyResourcesAssociatedWithRequestHandlers() {
- final PluginBag<SolrRequestHandler> handlerPluginBag =
- new PluginBag<>(SolrRequestHandler.class, null);
+ final RequestHandlerBag handlerPluginBag =
+ new RequestHandlerBag(null);
assertFalse(handlerPluginBag.getJerseyEndpoints().isRegistered(ListConfigSetsAPI.class));
handlerPluginBag.put("/foo", new ConfigSetsHandler(coreContainer));
diff --git a/solr/core/src/test/org/apache/solr/core/RequestHandlersTest.java b/solr/core/src/test/org/apache/solr/core/RequestHandlersTest.java
index 7ac9d6a107e..42fd4a466ab 100644
--- a/solr/core/src/test/org/apache/solr/core/RequestHandlersTest.java
+++ b/solr/core/src/test/org/apache/solr/core/RequestHandlersTest.java
@@ -52,7 +52,7 @@ public class RequestHandlersTest extends SolrTestCaseJ4 {
public void testLazyLoading() {
SolrCore core = h.getCore();
PluginBag.PluginHolder<SolrRequestHandler> handler =
- core.getRequestHandlers().getRegistry().get("/lazy");
+ core.getRequestHandlers().getHolder("/lazy");
assertFalse(handler.isLoaded());
assertU(