This is an automated email from the ASF dual-hosted git repository.
epugh pushed a commit to branch main
in repository https://gitbox.apache.org/repos/asf/solr.git
The following commit(s) were added to refs/heads/main by this push:
new 4f40e977a33 SOLR-18085: Remove use of "wt=standard" internally to
Solr. (#4080)
4f40e977a33 is described below
commit 4f40e977a337d440c598b6f37156045e5bd8a926
Author: Eric Pugh <[email protected]>
AuthorDate: Tue Feb 10 11:08:55 2026 -0500
SOLR-18085: Remove use of "wt=standard" internally to Solr. (#4080)
Updates Solr’s response-writer (wt) handling to remove reliance on the
legacy "standard" writer and to fail fast when an unknown response writer is
requested. Additionally we migrate from throwing a 500 error to a more
appropriate 400 error when a non existing response-write is specified.
---
changelog/unreleased/SOLR-18085.yml | 8 ++
.../src/java/org/apache/solr/core/PluginBag.java | 2 +-
.../java/org/apache/solr/core/RequestHandlers.java | 2 +-
.../src/java/org/apache/solr/core/SolrCore.java | 7 +-
.../org/apache/solr/request/SolrQueryRequest.java | 9 +--
.../apache/solr/response/RawResponseWriter.java | 9 ++-
.../solr/response/ResponseWritersRegistry.java | 88 ++++++++++++++++------
.../java/org/apache/solr/servlet/HttpSolrCall.java | 2 +-
.../apache/solr/servlet/SolrRequestParsers.java | 56 ++++----------
.../src/test/org/apache/solr/OutputWriterTest.java | 21 +-----
.../apache/solr/handler/V2ApiIntegrationTest.java | 35 ++++-----
.../response/TestPrometheusResponseWriter.java | 1 +
.../solr/response/TestRawResponseWriter.java | 13 ++--
.../solr/response/TestResponseWritersRegistry.java | 23 +-----
solr/packaging/test/test_rolling_upgrade.bats | 2 +-
.../src/java/org/apache/solr/util/TestHarness.java | 1 +
16 files changed, 134 insertions(+), 145 deletions(-)
diff --git a/changelog/unreleased/SOLR-18085.yml
b/changelog/unreleased/SOLR-18085.yml
new file mode 100644
index 00000000000..d6ca801ddc8
--- /dev/null
+++ b/changelog/unreleased/SOLR-18085.yml
@@ -0,0 +1,8 @@
+# See https://github.com/apache/solr/blob/main/dev-docs/changelog.adoc
+title: Removed the wt=standard concept that was used internally by Solr.
+type: removed # added, changed, fixed, deprecated, removed, dependency_update,
security, other
+authors:
+ - name: Eric Pugh
+links:
+ - name: SOLR-18085
+ url: https://issues.apache.org/jira/browse/SOLR-18085
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 7624a4c13dd..1af3445e7aa 100644
--- a/solr/core/src/java/org/apache/solr/core/PluginBag.java
+++ b/solr/core/src/java/org/apache/solr/core/PluginBag.java
@@ -202,7 +202,7 @@ public class PluginBag<T> implements AutoCloseable {
* Fetches a plugin by name , or the default
*
* @param name name using which it is registered
- * @param useDefault Return the default , if a plugin by that name does not
exist
+ * @param useDefault Return the default, if a plugin by that name does not
exist
*/
public T get(String name, boolean useDefault) {
T result = get(name);
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..39f043d95f9 100644
--- a/solr/core/src/java/org/apache/solr/core/RequestHandlers.java
+++ b/solr/core/src/java/org/apache/solr/core/RequestHandlers.java
@@ -117,7 +117,7 @@ public final class RequestHandlers {
modifiedInfos.add(applyInitParams(config, info));
}
handlers.init(Collections.emptyMap(), core, modifiedInfos);
- handlers.alias(handlers.getDefault(), "");
+
if (log.isDebugEnabled()) {
log.debug("Registered paths: {}", StrUtils.join(new
ArrayList<>(handlers.keySet()), ','));
}
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 c3aac28380e..c936dda686f 100644
--- a/solr/core/src/java/org/apache/solr/core/SolrCore.java
+++ b/solr/core/src/java/org/apache/solr/core/SolrCore.java
@@ -3131,14 +3131,11 @@ public class SolrCore implements SolrInfoBean,
Closeable {
// Initialize with the built defaults
responseWriters.init(defaultWriters, this);
-
- // configure the default response writer; this one should never be null
- if (responseWriters.getDefault() == null)
responseWriters.setDefault("standard");
}
- /** Finds a writer by name, or returns the default writer if not found. */
+ /** Finds a writer by name, or null if not found. */
public final QueryResponseWriter getQueryResponseWriter(String writerName) {
- return responseWriters.get(writerName, true);
+ return responseWriters.get(writerName, false);
}
/**
diff --git a/solr/core/src/java/org/apache/solr/request/SolrQueryRequest.java
b/solr/core/src/java/org/apache/solr/request/SolrQueryRequest.java
index 0ce4d82e551..c4aecf0c47e 100644
--- a/solr/core/src/java/org/apache/solr/request/SolrQueryRequest.java
+++ b/solr/core/src/java/org/apache/solr/request/SolrQueryRequest.java
@@ -204,14 +204,7 @@ public interface SolrQueryRequest extends AutoCloseable {
*/
default QueryResponseWriter getResponseWriter() {
// it's weird this method is here instead of SolrQueryResponse, but it's
practical/convenient
- SolrCore core = getCore();
- String wt = getParams().get(CommonParams.WT);
- // Use core writers if available, otherwise fall back to built-in writers
- if (core != null) {
- return core.getQueryResponseWriter(wt);
- } else {
- return ResponseWritersRegistry.getWriter(wt);
- }
+ return ResponseWritersRegistry.getWriter(getParams().get(CommonParams.WT),
getCore());
}
/**
diff --git a/solr/core/src/java/org/apache/solr/response/RawResponseWriter.java
b/solr/core/src/java/org/apache/solr/response/RawResponseWriter.java
index 922b4932952..fe5269497ff 100644
--- a/solr/core/src/java/org/apache/solr/response/RawResponseWriter.java
+++ b/solr/core/src/java/org/apache/solr/response/RawResponseWriter.java
@@ -47,7 +47,7 @@ public class RawResponseWriter implements QueryResponseWriter
{
*/
public static final String CONTENT = "content";
- private String _baseWriter = null;
+ private String baseWriter = null;
/**
* A fallback writer used for requests that don't return raw content and
that aren't associated
@@ -62,14 +62,17 @@ public class RawResponseWriter implements
QueryResponseWriter {
if (n != null) {
Object base = n.get("base");
if (base != null) {
- _baseWriter = base.toString();
+ baseWriter = base.toString();
}
}
}
protected QueryResponseWriter getBaseWriter(SolrQueryRequest request) {
if (request.getCore() != null) {
- return request.getCore().getQueryResponseWriter(_baseWriter);
+ // When baseWriter is null, use the core's default writer
(useDefault=true)
+ // Otherwise, look up the specific writer by name (useDefault=false for
explicit lookups)
+ boolean useDefault = (baseWriter == null);
+ return request.getCore().getResponseWriters().get(baseWriter,
useDefault);
}
// Requests to a specific core already have writers, but we still need a
'default writer' for
diff --git
a/solr/core/src/java/org/apache/solr/response/ResponseWritersRegistry.java
b/solr/core/src/java/org/apache/solr/response/ResponseWritersRegistry.java
index 67ec648cbf6..230b8caf99c 100644
--- a/solr/core/src/java/org/apache/solr/response/ResponseWritersRegistry.java
+++ b/solr/core/src/java/org/apache/solr/response/ResponseWritersRegistry.java
@@ -20,7 +20,9 @@ import static
org.apache.solr.util.stats.MetricUtils.OPEN_METRICS_WT;
import static org.apache.solr.util.stats.MetricUtils.PROMETHEUS_METRICS_WT;
import java.util.Map;
+import org.apache.solr.common.SolrException;
import org.apache.solr.common.params.CommonParams;
+import org.apache.solr.core.SolrCore;
import org.apache.solr.handler.admin.api.ReplicationAPIBase;
/**
@@ -46,23 +48,14 @@ public class ResponseWritersRegistry {
PrometheusResponseWriter prometheusWriter = new PrometheusResponseWriter();
BUILTIN_WRITERS =
- Map.of(
- CommonParams.JAVABIN,
- new JavaBinResponseWriter(),
- CommonParams.JSON,
- jsonWriter,
- "standard",
- jsonWriter, // Alias for JSON
- "xml",
- new XMLResponseWriter(),
- "raw",
- new RawResponseWriter(),
- PROMETHEUS_METRICS_WT,
- prometheusWriter,
- OPEN_METRICS_WT,
- prometheusWriter,
- ReplicationAPIBase.FILE_STREAM,
- new FileStreamResponseWriter());
+ Map.ofEntries(
+ Map.entry(CommonParams.JAVABIN, new JavaBinResponseWriter()),
+ Map.entry(CommonParams.JSON, jsonWriter),
+ Map.entry("xml", new XMLResponseWriter()),
+ Map.entry("raw", new RawResponseWriter()),
+ Map.entry(PROMETHEUS_METRICS_WT, prometheusWriter),
+ Map.entry(OPEN_METRICS_WT, prometheusWriter),
+ Map.entry(ReplicationAPIBase.FILE_STREAM, new
FileStreamResponseWriter()));
}
/**
@@ -71,17 +64,68 @@ public class ResponseWritersRegistry {
* <p>Built-in writers are always available and provide essential formats
needed by admin APIs and
* core functionality. They do not depend on core configuration or
ImplicitPlugins.json settings.
*
- * <p>If the requested writer is not available, returns the "standard"
(JSON) writer as a
- * fallback. This ensures requests always get a valid response format.
+ * <p>If the requested writer is not available, returns the JSON writer as a
fallback. This
+ * ensures requests always get a valid response format.
*
* @param writerName the writer name (e.g., "json", "xml", "javabin"), or
null for default
- * @return the response writer, never null (returns "standard"/JSON if not
found)
+ * @return the response writer, never null (returns JSON if not found)
*/
public static QueryResponseWriter getWriter(String writerName) {
if (writerName == null || writerName.isEmpty()) {
- return BUILTIN_WRITERS.get("standard");
+ writerName = CommonParams.JSON;
}
- return BUILTIN_WRITERS.getOrDefault(writerName,
BUILTIN_WRITERS.get("standard"));
+ return BUILTIN_WRITERS.get(writerName);
+ }
+
+ /**
+ * Gets a response writer, trying the core's registry first, then falling
back to built-in
+ * writers. This is the unified entry point for all writer resolution.
+ *
+ * <p>Resolution order:
+ *
+ * <ol>
+ * <li>If core is provided, check core's writer registry
+ * <li>If not found in core (or no core), check built-in writers
+ * <li>If writer name is explicitly specified but not found anywhere,
throw exception
+ * <li>If writer name is null/empty, return default (JSON)
+ * </ol>
+ *
+ * @param writerName the writer name (e.g., "json", "xml", "javabin"), or
null for default
+ * @param core the SolrCore to check first, or null for node-level requests
+ * @return the response writer, never null
+ * @throws SolrException if an explicitly requested writer type is not found
+ */
+ public static QueryResponseWriter getWriter(String writerName, SolrCore
core) {
+ QueryResponseWriter writer = null;
+
+ // Try core registry first if available
+ if (core != null) {
+ writer = core.getQueryResponseWriter(writerName);
+ }
+
+ // If not found and writer is explicitly requested, validate it exists in
built-in
+ if (writer == null) {
+ if (!hasWriter(writerName)) {
+ throw new SolrException(
+ SolrException.ErrorCode.BAD_REQUEST, "Unknown response writer
type: " + writerName);
+ } else {
+ writer = getWriter(writerName);
+ }
+ }
+ return writer;
+ }
+
+ /**
+ * Checks if a writer with the given name exists in the built-in writers.
+ *
+ * @param writerName the writer name to check
+ * @return true if the writer exists, false otherwise
+ */
+ public static boolean hasWriter(String writerName) {
+ if (writerName == null || writerName.isEmpty()) {
+ return true; // null/empty is valid, will use default
+ }
+ return BUILTIN_WRITERS.containsKey(writerName);
}
/**
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 a77541be552..c289ca6a3a9 100644
--- a/solr/core/src/java/org/apache/solr/servlet/HttpSolrCall.java
+++ b/solr/core/src/java/org/apache/solr/servlet/HttpSolrCall.java
@@ -727,7 +727,7 @@ public class HttpSolrCall {
protected void logAndFlushAdminRequest(SolrQueryResponse solrResp) throws
IOException {
if (solrResp.getToLog().size() > 0) {
- // has to come second and in it's own if to keep ./gradlew check happy.
+ // has to come second and in its own "if" to keep ./gradlew check happy.
if (log.isInfoEnabled()) {
log.info(
handler != null
diff --git a/solr/core/src/java/org/apache/solr/servlet/SolrRequestParsers.java
b/solr/core/src/java/org/apache/solr/servlet/SolrRequestParsers.java
index 3cf12aa7982..e835d844db8 100644
--- a/solr/core/src/java/org/apache/solr/servlet/SolrRequestParsers.java
+++ b/solr/core/src/java/org/apache/solr/servlet/SolrRequestParsers.java
@@ -67,13 +67,6 @@ public class SolrRequestParsers {
private static final Logger log =
LoggerFactory.getLogger(MethodHandles.lookup().lookupClass());
- // Should these constants be in a more public place?
- public static final String MULTIPART = "multipart";
- public static final String FORMDATA = "formdata";
- public static final String RAW = "raw";
- public static final String SIMPLE = "simple";
- public static final String STANDARD = "standard";
-
private static final Charset CHARSET_US_ASCII = StandardCharsets.US_ASCII;
public static final String INPUT_ENCODING_KEY = "ie";
@@ -81,8 +74,7 @@ public class SolrRequestParsers {
public static final String REQUEST_TIMER_SERVLET_ATTRIBUTE =
"org.apache.solr.RequestTimer";
- private final HashMap<String, SolrRequestParser> parsers = new HashMap<>();
- private StandardRequestParser standard;
+ private StandardRequestParser parser;
/**
* Default instance for e.g. admin requests. Limits to 2 MB uploads and does
not allow remote
@@ -91,7 +83,7 @@ public class SolrRequestParsers {
public static final SolrRequestParsers DEFAULT = new SolrRequestParsers();
/**
- * Pass in an xml configuration. A null configuration will enable everything
with maximum values.
+ * Pass in a xml configuration. A null configuration will enable everything
with maximum values.
*/
public SolrRequestParsers(SolrConfig globalConfig) {
final int multipartUploadLimitKB, formUploadLimitKB;
@@ -116,21 +108,12 @@ public class SolrRequestParsers {
MultipartRequestParser multi = new
MultipartRequestParser(multipartUploadLimitKB);
RawRequestParser raw = new RawRequestParser();
FormDataRequestParser formdata = new
FormDataRequestParser(formUploadLimitKB);
- standard = new StandardRequestParser(multi, raw, formdata);
-
- // I don't see a need to have this publicly configured just yet
- // adding it is trivial
- parsers.put(MULTIPART, multi);
- parsers.put(FORMDATA, formdata);
- parsers.put(RAW, raw);
- parsers.put(SIMPLE, new SimpleRequestParser());
- parsers.put(STANDARD, standard);
- parsers.put("", standard);
+ parser = new StandardRequestParser(multi, raw, formdata);
}
private static RTimerTree getRequestTimer(HttpServletRequest req) {
final Object reqTimer = req.getAttribute(REQUEST_TIMER_SERVLET_ATTRIBUTE);
- if (reqTimer != null && reqTimer instanceof RTimerTree) {
+ if (reqTimer instanceof RTimerTree) {
return ((RTimerTree) reqTimer);
}
@@ -139,7 +122,6 @@ public class SolrRequestParsers {
public SolrQueryRequest parse(SolrCore core, String path, HttpServletRequest
req)
throws Exception {
- SolrRequestParser parser = standard;
// TODO -- in the future, we could pick a different parser based on the
request
@@ -164,13 +146,12 @@ public class SolrRequestParsers {
/** For embedded Solr use; not related to HTTP. */
public SolrQueryRequest buildRequestFrom(
- SolrCore core, SolrParams params, Collection<ContentStream> streams)
throws Exception {
+ SolrCore core, SolrParams params, Collection<ContentStream> streams) {
return buildRequestFrom(core, params, streams, new RTimerTree(), null,
null);
}
public SolrQueryRequest buildRequestFrom(
- SolrCore core, SolrParams params, Collection<ContentStream> streams,
Principal principal)
- throws Exception {
+ SolrCore core, SolrParams params, Collection<ContentStream> streams,
Principal principal) {
return buildRequestFrom(core, params, streams, new RTimerTree(), null,
principal);
}
@@ -181,7 +162,7 @@ public class SolrRequestParsers {
RTimerTree requestTimer,
final HttpServletRequest req,
final Principal principal) // from req, if req was provided, otherwise
from elsewhere
- throws Exception {
+ {
// ensure streams is non-null and mutable so we can easily add to it
if (streams == null) {
streams = new ArrayList<>();
@@ -213,7 +194,7 @@ public class SolrRequestParsers {
@Override
public Map<String, String> getPathTemplateValues() {
- if (httpSolrCall != null && httpSolrCall instanceof V2HttpCall) {
+ if (httpSolrCall instanceof V2HttpCall) {
return ((V2HttpCall) httpSolrCall).getUrlParts();
}
return super.getPathTemplateValues();
@@ -337,9 +318,9 @@ public class SolrRequestParsers {
// we have no charset decoder until now, buffer the keys /
values for later
// processing:
buffer.add(keyBytes);
- buffer.add(Long.valueOf(keyPos));
+ buffer.add(keyPos);
buffer.add(valueBytes);
- buffer.add(Long.valueOf(valuePos));
+ buffer.add(valuePos);
} else {
// we already have a charsetDecoder, so we can directly decode
without buffering:
final String key = decodeChars(keyBytes, keyPos, charsetDecoder),
@@ -457,7 +438,7 @@ public class SolrRequestParsers {
// -----------------------------------------------------------------
// -----------------------------------------------------------------
- // I guess we don't really even need the interface, but i'll keep it here
just for kicks
+ // I guess we don't really even need the interface, but I'll keep it here
just for kicks
interface SolrRequestParser {
public SolrParams parseParamsAndFillStreams(
final HttpServletRequest req, ArrayList<ContentStream> streams) throws
Exception;
@@ -466,15 +447,6 @@ public class SolrRequestParsers {
// -----------------------------------------------------------------
// -----------------------------------------------------------------
- /** The simple parser just uses the params directly, does not support POST
URL-encoded forms */
- static class SimpleRequestParser implements SolrRequestParser {
- @Override
- public SolrParams parseParamsAndFillStreams(
- final HttpServletRequest req, ArrayList<ContentStream> streams) throws
Exception {
- return parseQueryString(req.getQueryString());
- }
- }
-
/** Wrap an HttpServletRequest as a ContentStream */
static class HttpRequestContentStream extends ContentStreamBase {
private final InputStream inputStream;
@@ -515,7 +487,7 @@ public class SolrRequestParsers {
|| req.getHeader("Transfer-Encoding") != null
|| !NO_BODY_METHODS.contains(req.getMethod())) {
// If Content-Length > 0 OR Transfer-Encoding exists OR
- // it's a method that can have a body (POST/PUT/PATCH etc)
+ // it's a method that can have a body (POST/PUT/PATCH etc.)
streams.add(new HttpRequestContentStream(req, req.getInputStream()));
}
@@ -543,7 +515,7 @@ public class SolrRequestParsers {
throw new SolrException(
ErrorCode.BAD_REQUEST, "Not multipart content! " +
req.getContentType());
}
- // Magic way to tell Jetty dynamically we want multi-part processing.
+ // Magic way to tell Jetty dynamically we want multipart processing.
// This is taken from:
//
https://github.com/eclipse/jetty.project/blob/jetty-10.0.12/jetty-server/src/main/java/org/eclipse/jetty/server/Request.java#L144
req.setAttribute("org.eclipse.jetty.multipartConfig",
multipartConfigElement);
@@ -735,7 +707,7 @@ public class SolrRequestParsers {
public SolrParams parseParamsAndFillStreams(
final HttpServletRequest req, ArrayList<ContentStream> streams) throws
Exception {
String contentType = req.getContentType();
- String method = req.getMethod(); // No need to uppercase... HTTP verbs
are case sensitive
+ String method = req.getMethod(); // No need to uppercase... HTTP verbs
are case-sensitive
String uri = req.getRequestURI();
boolean isV2 = getHttpSolrCall(req) instanceof V2HttpCall;
boolean isPost = "POST".equals(method);
diff --git a/solr/core/src/test/org/apache/solr/OutputWriterTest.java
b/solr/core/src/test/org/apache/solr/OutputWriterTest.java
index 30df9ed98fa..7f711631ce1 100644
--- a/solr/core/src/test/org/apache/solr/OutputWriterTest.java
+++ b/solr/core/src/test/org/apache/solr/OutputWriterTest.java
@@ -29,32 +29,16 @@ import org.junit.Test;
/** Tests the ability to configure multiple query output writers, and select
those at query time. */
public class OutputWriterTest extends SolrTestCaseJ4 {
- /** The XML string that's output for testing purposes. */
- public static final String USELESS_OUTPUT = "useless output";
-
@BeforeClass
public static void beforeClass() throws Exception {
initCore("solr/crazy-path-to-config.xml", "solr/crazy-path-to-schema.xml");
}
- /**
- * responseHeader has changed in SOLR-59, check old and new variants, In
SOLR-2413, we removed
- * support for the deprecated versions
- */
- @Test
- public void testSOLR59responseHeaderVersions() {
- // default results in "new" responseHeader
- lrf.args.put("wt", "standard");
- assertQ(req("foo"),
"/response/lst[@name='responseHeader']/int[@name='status'][.='0']");
- lrf.args.remove("wt");
- assertQ(req("foo"),
"/response/lst[@name='responseHeader']/int[@name='QTime']");
- }
-
@Test
public void testUselessWriter() throws Exception {
lrf.args.put("wt", "useless");
String out = h.query(req("foo"));
- assertEquals(USELESS_OUTPUT, out);
+ assertEquals(UselessOutputWriter.USELESS_OUTPUT, out);
}
public void testLazy() {
@@ -71,6 +55,9 @@ public class OutputWriterTest extends SolrTestCaseJ4 {
/** An output writer that doesn't do anything useful. */
public static class UselessOutputWriter implements TextQueryResponseWriter {
+ /** The XML string that's output for testing purposes. */
+ public static final String USELESS_OUTPUT = "useless output";
+
public UselessOutputWriter() {}
@Override
diff --git
a/solr/core/src/test/org/apache/solr/handler/V2ApiIntegrationTest.java
b/solr/core/src/test/org/apache/solr/handler/V2ApiIntegrationTest.java
index 3b7a85eb096..4ef3c7f48df 100644
--- a/solr/core/src/test/org/apache/solr/handler/V2ApiIntegrationTest.java
+++ b/solr/core/src/test/org/apache/solr/handler/V2ApiIntegrationTest.java
@@ -48,7 +48,7 @@ import org.junit.BeforeClass;
import org.junit.Test;
public class V2ApiIntegrationTest extends SolrCloudTestCase {
- private static String COLL_NAME = "collection1";
+ private static final String COLL_NAME = "collection1";
@BeforeClass
public static void createCluster() throws Exception {
@@ -80,11 +80,7 @@ public class V2ApiIntegrationTest extends SolrCloudTestCase {
.build();
v2Request.setResponseParser(responseParser);
RemoteSolrException ex =
- expectThrows(
- RemoteSolrException.class,
- () -> {
- v2Request.process(cluster.getSolrClient());
- });
+ expectThrows(RemoteSolrException.class, () ->
v2Request.process(cluster.getSolrClient()));
assertEquals(expectedCode, ex.code());
}
@@ -114,28 +110,29 @@ public class V2ApiIntegrationTest extends
SolrCloudTestCase {
}
@Test
- public void testWTParam() throws Exception {
+ public void testInvalidWTParamReturnsError() throws Exception {
V2Request request = new V2Request.Builder("/c/" + COLL_NAME +
"/get/_introspect").build();
- // TODO: If possible do this in a better way
+ // Using an invalid wt parameter should return a 400 error
request.setResponseParser(new InputStreamResponseParser("bleh"));
NamedList<Object> res = cluster.getSolrClient().request(request);
String respString = InputStreamResponseParser.consumeResponseToString(res);
- assertFalse(respString.contains("<body><h2>HTTP ERROR 500</h2>"));
- assertFalse(respString.contains("500"));
- assertFalse(respString.contains("NullPointerException"));
- assertFalse(
- respString.contains(
- "<p>Problem accessing /solr/____v2/c/collection1/get/_introspect.
Reason:"));
- // since no-op response writer is used, doing contains match
- assertTrue(respString.contains("/c/collection1/get"));
+ // Should get a 400 Bad Request error for unknown writer type
+ assertTrue(
+ "Expected error message about unknown writer type",
+ respString.contains("Unknown response writer type"));
+ assertTrue("Expected 400 error code", respString.contains("400"));
+ }
- // no response parser
+ @Test
+ public void testWTParam() throws Exception {
+ // When no response parser is set, the default JSON writer should be used
+ V2Request request = new V2Request.Builder("/c/" + COLL_NAME +
"/get/_introspect").build();
request.setResponseParser(null);
Map<?, ?> resp = resAsMap(cluster.getSolrClient(), request);
- respString = resp.toString();
+ String respString = resp.toString();
- assertFalse(respString.contains("<body><h2>HTTP ERROR 500</h2>"));
+ assertFalse(respString.contains("400"));
assertFalse(
respString.contains(
"<p>Problem accessing /solr/____v2/c/collection1/get/_introspect.
Reason:"));
diff --git
a/solr/core/src/test/org/apache/solr/response/TestPrometheusResponseWriter.java
b/solr/core/src/test/org/apache/solr/response/TestPrometheusResponseWriter.java
index 530a2ba6009..a8250a1ba3a 100644
---
a/solr/core/src/test/org/apache/solr/response/TestPrometheusResponseWriter.java
+++
b/solr/core/src/test/org/apache/solr/response/TestPrometheusResponseWriter.java
@@ -194,6 +194,7 @@ public class TestPrometheusResponseWriter extends
SolrTestCaseJ4 {
try (SolrClient adminClient =
getHttpSolrClient(solrTestRule.getBaseUrl())) {
NamedList<Object> res = adminClient.request(req);
+ // Unknown wt parameter should return a 400 error
assertEquals(400, res.get("responseStatus"));
}
}
diff --git
a/solr/core/src/test/org/apache/solr/response/TestRawResponseWriter.java
b/solr/core/src/test/org/apache/solr/response/TestRawResponseWriter.java
index 7b822b18848..34e006b727b 100644
--- a/solr/core/src/test/org/apache/solr/response/TestRawResponseWriter.java
+++ b/solr/core/src/test/org/apache/solr/response/TestRawResponseWriter.java
@@ -56,7 +56,9 @@ public class TestRawResponseWriter extends SolrTestCaseJ4 {
// we spin up.
initCore("solrconfig.xml", "schema.xml");
- writerNoBase = newRawResponseWriter(null); /* defaults to standard writer
as base */
+ writerNoBase =
+ newRawResponseWriter(
+ null); /* null base uses core's default writer (XML for this
core), or JSON if no core */
writerXmlBase = newRawResponseWriter("xml");
writerJsonBase = newRawResponseWriter("json");
writerBinBase = newRawResponseWriter("javabin");
@@ -120,7 +122,7 @@ public class TestRawResponseWriter extends SolrTestCaseJ4 {
// we should have UTF-8 Bytes if we use an OutputStream
ByteArrayOutputStream bout = new ByteArrayOutputStream();
writer.write(bout, req(), rsp);
- assertEquals(data, bout.toString(StandardCharsets.UTF_8.toString()));
+ assertEquals(data, bout.toString(StandardCharsets.UTF_8));
}
}
@@ -153,13 +155,12 @@ public class TestRawResponseWriter extends SolrTestCaseJ4
{
assertEquals(xml, writerXmlBase.writeToString(req(), rsp));
ByteArrayOutputStream xmlBout = new ByteArrayOutputStream();
writerXmlBase.write(xmlBout, req(), rsp);
- assertEquals(xml, xmlBout.toString(StandardCharsets.UTF_8.toString()));
+ assertEquals(xml, xmlBout.toString(StandardCharsets.UTF_8));
- //
assertEquals(xml, writerNoBase.writeToString(req(), rsp));
ByteArrayOutputStream noneBout = new ByteArrayOutputStream();
writerNoBase.write(noneBout, req(), rsp);
- assertEquals(xml, noneBout.toString(StandardCharsets.UTF_8.toString()));
+ assertEquals(xml, noneBout.toString(StandardCharsets.UTF_8));
// json
String json = "{\n" + " \"content\":\"test\",\n" + " \"foo\":\"bar\"}\n";
@@ -206,7 +207,7 @@ public class TestRawResponseWriter extends SolrTestCaseJ4 {
}
/**
- * Generates a new {@link RawResponseWriter} wrapping the specified
baseWriter name (which much
+ * Generates a new {@link RawResponseWriter} wrapping the specified
baseWriter name (which must
* either be an implicitly defined response writer, or one explicitly
configured in
* solrconfig.xml)
*
diff --git
a/solr/core/src/test/org/apache/solr/response/TestResponseWritersRegistry.java
b/solr/core/src/test/org/apache/solr/response/TestResponseWritersRegistry.java
index 695ad0e1278..0ab46734b38 100644
---
a/solr/core/src/test/org/apache/solr/response/TestResponseWritersRegistry.java
+++
b/solr/core/src/test/org/apache/solr/response/TestResponseWritersRegistry.java
@@ -31,34 +31,19 @@ public class TestResponseWritersRegistry extends
SolrTestCaseJ4 {
@Test
public void testBuiltInWriterFallbackBehavior() {
- QueryResponseWriter standardWriter =
ResponseWritersRegistry.getWriter("standard");
+ QueryResponseWriter defaultWriter =
ResponseWritersRegistry.getWriter("json");
// Test null fallback
QueryResponseWriter nullWriter = ResponseWritersRegistry.getWriter(null);
- assertThat("null writer should not be null", nullWriter,
is(not(nullValue())));
- assertThat("null writer should be same as standard", nullWriter,
is(standardWriter));
+ assertThat("null writer should be same as default", nullWriter,
is(defaultWriter));
// Test empty string fallback
QueryResponseWriter emptyWriter = ResponseWritersRegistry.getWriter("");
assertThat("empty writer should not be null", emptyWriter,
is(not(nullValue())));
- assertThat("empty writer should be same as standard", emptyWriter,
is(standardWriter));
+ assertThat("empty writer should be same as default", emptyWriter,
is(defaultWriter));
// Test unknown format fallback
QueryResponseWriter unknownWriter =
ResponseWritersRegistry.getWriter("nonexistent");
- assertThat("unknown writer should not be null", unknownWriter,
is(not(nullValue())));
- assertThat("unknown writer should be same as standard", unknownWriter,
is(standardWriter));
- }
-
- @Test
- public void testBuiltInWriterLimitedSet() {
- QueryResponseWriter standardWriter =
ResponseWritersRegistry.getWriter("standard");
-
- // Built-in writers should NOT include extended format writers (csv,
geojson, etc.)
- // These should all fall back to standard
- // I think this standard thing is weird... I think it should throw an
exception!
- assertThat(
- "geojson should fall back to standard",
- ResponseWritersRegistry.getWriter("geojson"),
- is(standardWriter));
+ assertThat("unknown writer should be null", unknownWriter,
is(nullValue()));
}
}
diff --git a/solr/packaging/test/test_rolling_upgrade.bats
b/solr/packaging/test/test_rolling_upgrade.bats
index 3902189eeb3..ae956a868ba 100644
--- a/solr/packaging/test/test_rolling_upgrade.bats
+++ b/solr/packaging/test/test_rolling_upgrade.bats
@@ -19,7 +19,7 @@ load bats_helper
# You can test alternative images via
# export SOLR_BEGIN_IMAGE="apache/solr-nightly:9.9.0-slim" and then running
-# ./gradlw iTest --tests test_docker_solrcloud.bats
+# ./gradlew iTest --tests test_rolling_upgrade.bats
SOLR_BEGIN_IMAGE="${SOLR_BEGIN_IMAGE:-apache/solr-nightly:9.10.0-SNAPSHOT-slim}"
SOLR_END_IMAGE="${SOLR_END_IMAGE:-apache/solr-nightly:10.0.0-SNAPSHOT-slim}"
diff --git a/solr/test-framework/src/java/org/apache/solr/util/TestHarness.java
b/solr/test-framework/src/java/org/apache/solr/util/TestHarness.java
index 29caa318a04..a933605466f 100644
--- a/solr/test-framework/src/java/org/apache/solr/util/TestHarness.java
+++ b/solr/test-framework/src/java/org/apache/solr/util/TestHarness.java
@@ -419,6 +419,7 @@ public class TestHarness extends BaseTestHarness {
@SuppressWarnings({"unchecked"})
public LocalSolrQueryRequest makeRequest(String... q) {
if (q.length == 1) {
+ args.computeIfAbsent("wt", k -> "xml");
return new LocalSolrQueryRequest(
TestHarness.this.getCore(), q[0], qtype, start, limit, args);
}