This is an automated email from the ASF dual-hosted git repository.
epugh pushed a commit to branch branch_10x
in repository https://gitbox.apache.org/repos/asf/solr.git
The following commit(s) were added to refs/heads/branch_10x by this push:
new 746e8565833 SOLR-18095: Add ability to map writer types and handlers
to a No Operation version. (#4091)
746e8565833 is described below
commit 746e8565833570a9146799682a03828874cc7c55
Author: Eric Pugh <[email protected]>
AuthorDate: Wed Feb 18 05:23:29 2026 -0500
SOLR-18095: Add ability to map writer types and handlers to a No Operation
version. (#4091)
This approach for specifically response writers existed in previous
versions of Solr as a hidden feature/side effect of something else and was
removed. It's now restored for the specific purpose of disabling
ImplicitPlugins created components.
(cherry picked from commit e68d292f0506449707cc4a079c8f7d5da221d651)
---
changelog/unreleased/SOLR-18095.yml | 8 ++
...RequestHandler.java => NoOpRequestHandler.java} | 6 +-
.../NoOpResponseWriter.java} | 26 ++----
.../solr/collection1/conf/solrconfig-noop.xml | 57 +++++++++++++
.../solr/handler/NoOpRequestHandlerTest.java | 97 ++++++++++++++++++++++
.../solr/response/NoOpResponseWriterTest.java | 73 ++++++++++++++++
.../pages/implicit-requesthandlers.adoc | 12 +++
.../query-guide/pages/response-writers.adoc | 13 +++
8 files changed, 272 insertions(+), 20 deletions(-)
diff --git a/changelog/unreleased/SOLR-18095.yml
b/changelog/unreleased/SOLR-18095.yml
new file mode 100644
index 00000000000..8884ef9ab2d
--- /dev/null
+++ b/changelog/unreleased/SOLR-18095.yml
@@ -0,0 +1,8 @@
+# See https://github.com/apache/solr/blob/main/dev-docs/changelog.adoc
+title: Provide NoOpRequestWriter and NoOpRequestHandler that can be used to
disable implicitly configured equivalents.
+type: added # added, changed, fixed, deprecated, removed, dependency_update,
security, other
+authors:
+ - name: Eric Pugh
+links:
+ - name: SOLR-18095
+ url: https://issues.apache.org/jira/browse/SOLR-18095
diff --git
a/solr/core/src/java/org/apache/solr/handler/NotFoundRequestHandler.java
b/solr/core/src/java/org/apache/solr/handler/NoOpRequestHandler.java
similarity index 86%
copy from solr/core/src/java/org/apache/solr/handler/NotFoundRequestHandler.java
copy to solr/core/src/java/org/apache/solr/handler/NoOpRequestHandler.java
index 50e2fa1f27c..6ce2e82d877 100644
--- a/solr/core/src/java/org/apache/solr/handler/NotFoundRequestHandler.java
+++ b/solr/core/src/java/org/apache/solr/handler/NoOpRequestHandler.java
@@ -23,12 +23,12 @@ import org.apache.solr.request.SolrQueryRequest;
import org.apache.solr.response.SolrQueryResponse;
import org.apache.solr.security.AuthorizationContext;
-/** Does nothing other than showing a 404 message */
-public class NotFoundRequestHandler extends RequestHandlerBase {
+/** Does nothing other than showing a 403 message */
+public class NoOpRequestHandler extends RequestHandlerBase {
@Override
public void handleRequestBody(SolrQueryRequest req, SolrQueryResponse rsp)
throws Exception {
throw new SolrException(
- SolrException.ErrorCode.NOT_FOUND, "" + req.getContext().get(PATH) + "
is not found");
+ SolrException.ErrorCode.FORBIDDEN, req.getContext().get(PATH) + " has
been disabled");
}
@Override
diff --git
a/solr/core/src/java/org/apache/solr/handler/NotFoundRequestHandler.java
b/solr/core/src/java/org/apache/solr/response/NoOpResponseWriter.java
similarity index 54%
rename from
solr/core/src/java/org/apache/solr/handler/NotFoundRequestHandler.java
rename to solr/core/src/java/org/apache/solr/response/NoOpResponseWriter.java
index 50e2fa1f27c..125f3338f20 100644
--- a/solr/core/src/java/org/apache/solr/handler/NotFoundRequestHandler.java
+++ b/solr/core/src/java/org/apache/solr/response/NoOpResponseWriter.java
@@ -14,30 +14,22 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
-package org.apache.solr.handler;
+package org.apache.solr.response;
-import static org.apache.solr.common.params.CommonParams.PATH;
-
-import org.apache.solr.common.SolrException;
+import java.io.IOException;
+import java.io.Writer;
import org.apache.solr.request.SolrQueryRequest;
-import org.apache.solr.response.SolrQueryResponse;
-import org.apache.solr.security.AuthorizationContext;
-/** Does nothing other than showing a 404 message */
-public class NotFoundRequestHandler extends RequestHandlerBase {
- @Override
- public void handleRequestBody(SolrQueryRequest req, SolrQueryResponse rsp)
throws Exception {
- throw new SolrException(
- SolrException.ErrorCode.NOT_FOUND, "" + req.getContext().get(PATH) + "
is not found");
- }
+public class NoOpResponseWriter implements TextQueryResponseWriter {
+ static String MESSAGE = "noop response writer";
@Override
- public String getDescription() {
- return "No Operation";
+ public void write(Writer writer, SolrQueryRequest req, SolrQueryResponse
rsp) throws IOException {
+ writer.write(MESSAGE);
}
@Override
- public Name getPermissionName(AuthorizationContext request) {
- return Name.ALL;
+ public String getContentType(SolrQueryRequest request, SolrQueryResponse
response) {
+ return QueryResponseWriter.CONTENT_TYPE_TEXT_UTF8;
}
}
diff --git a/solr/core/src/test-files/solr/collection1/conf/solrconfig-noop.xml
b/solr/core/src/test-files/solr/collection1/conf/solrconfig-noop.xml
new file mode 100644
index 00000000000..2e9a5e463d0
--- /dev/null
+++ b/solr/core/src/test-files/solr/collection1/conf/solrconfig-noop.xml
@@ -0,0 +1,57 @@
+<?xml version="1.0" ?>
+
+<!--
+ 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.
+-->
+
+<!-- Test config that demonstrates overriding implicit handlers and response
writers with NoOp versions -->
+
+<config>
+
+ <dataDir>${solr.data.dir:}</dataDir>
+
+ <schemaFactory class="ClassicIndexSchemaFactory"/>
+
+ <luceneMatchVersion>${tests.luceneMatchVersion:LATEST}</luceneMatchVersion>
+
+ <updateHandler class="solr.DirectUpdateHandler2">
+ <updateLog enable="${solr.index.updatelog.enabled:true}">
+ <str name="dir">${solr.ulog.dir:}</str>
+ </updateLog>
+ </updateHandler>
+
+ <!--
+ Override the implicit /schema handler (from ImplicitPlugins.json)
+ with NoOpRequestHandler to demonstrate that implicit handlers can be
disabled
+ -->
+ <requestHandler name="/schema" class="solr.NoOpRequestHandler" />
+
+ <!-- Standard search handler for testing other functionality still works -->
+ <requestHandler name="/select" class="solr.SearchHandler">
+ <lst name="defaults">
+ <str name="echoParams">explicit</str>
+ <str name="indent">true</str>
+ <str name="df">text</str>
+ </lst>
+ </requestHandler>
+
+ <!--
+ Override the implicit CSV response writer (from ImplicitPlugins.json)
+ with NoOpResponseWriter to demonstrate that implicit response writers can
be disabled
+ -->
+ <queryResponseWriter name="csv" class="solr.NoOpResponseWriter" />
+
+</config>
diff --git
a/solr/core/src/test/org/apache/solr/handler/NoOpRequestHandlerTest.java
b/solr/core/src/test/org/apache/solr/handler/NoOpRequestHandlerTest.java
new file mode 100644
index 00000000000..4193a7829bd
--- /dev/null
+++ b/solr/core/src/test/org/apache/solr/handler/NoOpRequestHandlerTest.java
@@ -0,0 +1,97 @@
+/*
+ * 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;
+
+import org.apache.solr.SolrTestCaseJ4;
+import org.apache.solr.common.SolrException;
+import org.apache.solr.request.SolrQueryRequest;
+import org.apache.solr.response.SolrQueryResponse;
+import org.junit.BeforeClass;
+import org.junit.Test;
+
+/**
+ * Test that demonstrates NoOpRequestHandler can be used to disable implicit
handlers like
+ * SchemaHandler that are loaded via ImplicitPlugins.json.
+ */
+public class NoOpRequestHandlerTest extends SolrTestCaseJ4 {
+
+ @BeforeClass
+ public static void beforeClass() throws Exception {
+ initCore("solrconfig-noop.xml", "schema.xml");
+ }
+
+ @Test
+ public void testSchemaHandlerDisabled() {
+ // Test that /schema endpoint is disabled and returns 403 FORBIDDEN
+ SolrException exception =
+ expectThrows(
+ SolrException.class,
+ () -> {
+ try (SolrQueryRequest req = req("qt", "/schema")) {
+ SolrQueryResponse rsp = new SolrQueryResponse();
+ h.getCore().execute(h.getCore().getRequestHandler("/schema"),
req, rsp);
+ if (rsp.getException() != null) {
+ throw rsp.getException();
+ }
+ }
+ });
+
+ assertEquals(
+ "Should return FORBIDDEN status code",
+ SolrException.ErrorCode.FORBIDDEN.code,
+ exception.code());
+ assertTrue(
+ "Error message should indicate endpoint has been disabled",
+ exception.getMessage().contains("has been disabled"));
+ }
+
+ @Test
+ public void testSchemaHandlerSubPathDisabled() {
+ // Test that /schema/fields endpoint is also disabled
+ SolrException exception =
+ expectThrows(
+ SolrException.class,
+ () -> {
+ try (SolrQueryRequest req = req("qt", "/schema/fields")) {
+ SolrQueryResponse rsp = new SolrQueryResponse();
+ h.getCore().execute(h.getCore().getRequestHandler("/schema"),
req, rsp);
+ if (rsp.getException() != null) {
+ throw rsp.getException();
+ }
+ }
+ });
+
+ assertEquals(
+ "Should return FORBIDDEN status code",
+ SolrException.ErrorCode.FORBIDDEN.code,
+ exception.code());
+ }
+
+ @Test
+ public void testNoOpHandlerRegistered() {
+ // Verify that the NoOpRequestHandler is actually registered at /schema
+ assertNotNull("Schema handler should be registered",
h.getCore().getRequestHandler("/schema"));
+ assertTrue(
+ "Handler at /schema should be NoOpRequestHandler",
+ h.getCore().getRequestHandler("/schema") instanceof
NoOpRequestHandler);
+ }
+
+ @Test
+ public void testOtherHandlersStillWork() {
+ assertQ("Standard query handler should still work", req("q", "*:*"),
"//result[@numFound='0']");
+ }
+}
diff --git
a/solr/core/src/test/org/apache/solr/response/NoOpResponseWriterTest.java
b/solr/core/src/test/org/apache/solr/response/NoOpResponseWriterTest.java
new file mode 100644
index 00000000000..fc8888eda82
--- /dev/null
+++ b/solr/core/src/test/org/apache/solr/response/NoOpResponseWriterTest.java
@@ -0,0 +1,73 @@
+/*
+ * 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.response;
+
+import java.io.ByteArrayOutputStream;
+import java.io.IOException;
+import java.io.StringWriter;
+import java.io.Writer;
+import java.nio.charset.StandardCharsets;
+import org.apache.solr.SolrTestCaseJ4;
+import org.junit.BeforeClass;
+import org.junit.Test;
+
+/**
+ * Test that demonstrates NoOpResponseWriter can be used to disable implicit
response writers that
+ * are loaded via ImplicitPlugins.json.
+ */
+public class NoOpResponseWriterTest extends SolrTestCaseJ4 {
+
+ @BeforeClass
+ public static void beforeClass() throws Exception {
+ initCore("solrconfig-noop.xml", "schema.xml");
+ }
+
+ @Test
+ public void testWrite() throws IOException {
+ NoOpResponseWriter writer = new NoOpResponseWriter();
+
+ Writer stringWriter = new StringWriter();
+
+ writer.write(stringWriter, null, null);
+
+ assertEquals(NoOpResponseWriter.MESSAGE, stringWriter.toString());
+ }
+
+ @Test
+ public void testGetContentType() {
+ NoOpResponseWriter writer = new NoOpResponseWriter();
+
+ String contentType = writer.getContentType(null, null);
+ assertEquals(QueryResponseWriter.CONTENT_TYPE_TEXT_UTF8, contentType);
+ }
+
+ @Test
+ public void testCsvResponseWriterDisabled() throws Exception {
+ QueryResponseWriter csvWriter = h.getCore().getQueryResponseWriter("csv");
+
+ assertNotNull("CSV response writer should be registered", csvWriter);
+ assertTrue(
+ "CSV response writer should be NoOpResponseWriter, not the implicit
CSVResponseWriter",
+ csvWriter instanceof NoOpResponseWriter);
+
+ // Verify it returns the NoOp message when used
+ ByteArrayOutputStream out = new ByteArrayOutputStream();
+ csvWriter.write(out, null, null);
+ String output = out.toString(StandardCharsets.UTF_8);
+ assertEquals("CSV writer should return NoOp message",
NoOpResponseWriter.MESSAGE, output);
+ }
+}
diff --git
a/solr/solr-ref-guide/modules/configuration-guide/pages/implicit-requesthandlers.adoc
b/solr/solr-ref-guide/modules/configuration-guide/pages/implicit-requesthandlers.adoc
index 05784283e4d..16b2f691281 100644
---
a/solr/solr-ref-guide/modules/configuration-guide/pages/implicit-requesthandlers.adoc
+++
b/solr/solr-ref-guide/modules/configuration-guide/pages/implicit-requesthandlers.adoc
@@ -363,3 +363,15 @@ The response will look similar to:
Because implicit request handlers are not present in `solrconfig.xml`,
configuration of their associated `default`, `invariant` and `appends`
parameters may be edited via the xref:request-parameters-api.adoc[] using the
paramset listed in the above table.
However, other parameters, including SearchHandler components, may not be
modified.
The invariants and appends specified in the implicit configuration cannot be
overridden.
+
+== How to Disable an Implicit Handler
+
+You may want to disable the loading of an implicit handler.
+This is supported by remapping the name of the handler to the
`NoOpRequestHandler` in `solrconfig.xml`, which will return a 403 FORBIDDEN
status code.
+
+For example, to disable the `/update/csv` handler you would re-define it in
`solrconfig.xml` as:
+
+[source,xml]
+----
+<requestHandler name="/update/csv"
class="solr.NoOpRequestHandler"></requestHandler>
+----
diff --git
a/solr/solr-ref-guide/modules/query-guide/pages/response-writers.adoc
b/solr/solr-ref-guide/modules/query-guide/pages/response-writers.adoc
index b4f29b8e681..0aff169b739 100644
--- a/solr/solr-ref-guide/modules/query-guide/pages/response-writers.adoc
+++ b/solr/solr-ref-guide/modules/query-guide/pages/response-writers.adoc
@@ -32,6 +32,7 @@ The list below describe shows the most common settings for
the `wt` parameter, w
* <<Smile Response Writer,smile>>
* <<Standard XML Response Writer,xml>>
* <<XSLT Response Writer,xslt>>
+* <<NoOp Response Writer,noop>>
== JSON Response Writer
@@ -386,3 +387,15 @@ else:
== Smile Response Writer
The Smile format is a JSON-compatible binary format, described in detail here:
https://en.wikipedia.org/wiki/Smile_%28data_interchange_format%29[https://en.wikipedia.org/wiki/Smile_(data_interchange_format)]
+
+== NoOp Response Writer
+
+You may want to disable a specific response writer.
+This is supported by remapping the name of the response writer to the
`NoOpResponseWriter` in `solrconfig.xml`, which will return a 200 OK status
code with the plain text message `noop response writer`.
+
+For example, to disable the `csv` handler you would re-define it in
`solrconfig.xml` as:
+
+[source,xml]
+----
+<queryResponseWriter name="csv" class="solr.NoOpResponseWriter" />
+----