SOLR-18085: Review use of "wt=standard" and see if we can remove it.#4080
SOLR-18085: Review use of "wt=standard" and see if we can remove it.#4080epugh wants to merge 16 commits intoapache:mainfrom
Conversation
…s to work Some failing tests for plugins like CborResponseWriter that aren't in the content type --> wt converter.
…t found you get a 500 error. I think using a bad responsewriter should be an error, and we shoudln't cover it up, or return json...
solr/core/src/java/org/apache/solr/request/SolrQueryRequest.java
Outdated
Show resolved
Hide resolved
| handlers.init(Collections.emptyMap(), core, modifiedInfos); | ||
| handlers.alias(handlers.getDefault(), ""); | ||
| // Curious if this is actually needed! | ||
| // handlers.alias(handlers.getDefault(), ""); |
| } | ||
| } | ||
| // Default to JSON when no Accept header or unrecognized content type | ||
| return CommonParams.JSON; |
There was a problem hiding this comment.
i remain ambivalent about these... maybe okay? I mean, if I do a curl command don't provide wt=json OR the content types, maybe okay? It might be a perfectly nice thign for our users...
| public static final String SIMPLE = "simple"; | ||
| public static final String STANDARD = "standard"; | ||
| // public static final String MULTIPART = "multipart"; | ||
| // public static final String FORMDATA = "formdata"; |
There was a problem hiding this comment.
so many unused statics!
| 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 500 error |
There was a problem hiding this comment.
This is the Big Change.
There was a problem hiding this comment.
Pull request overview
Updates Solr’s response-writer (wt) handling to reduce reliance on the legacy "standard" writer and to fail fast when an unknown response writer is requested.
Changes:
- Adds stricter
wtvalidation and introduces anAccept-header fallback whenwtis absent. - Removes/neutralizes legacy
"standard"response-writer wiring and adjusts handler aliasing behavior. - Updates tests and test utilities to reflect the new error behavior and defaults.
Reviewed changes
Copilot reviewed 7 out of 7 changed files in this pull request and generated 8 comments.
Show a summary per file
| File | Description |
|---|---|
| solr/test-framework/src/java/org/apache/solr/util/TestHarness.java | Forces wt=xml in a common local test request path to preserve historical XML expectations. |
| solr/core/src/test/org/apache/solr/response/TestPrometheusResponseWriter.java | Updates expected status for unknown wt to 500. |
| solr/core/src/test/org/apache/solr/handler/V2ApiIntegrationTest.java | Splits wt tests and asserts 500 + message for invalid writer types. |
| solr/core/src/java/org/apache/solr/servlet/SolrRequestParsers.java | Comments out legacy constants/registry code (effectively disabling/removing it). |
| solr/core/src/java/org/apache/solr/request/SolrQueryRequest.java | Adds Accept header → wt mapping and throws 500 for unknown response writers. |
| solr/core/src/java/org/apache/solr/core/SolrCore.java | Removes "standard" alias from default writers and stops setting a default writer. |
| solr/core/src/java/org/apache/solr/core/RequestHandlers.java | Stops aliasing the configured default handler to the empty path. |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
solr/core/src/java/org/apache/solr/servlet/SolrRequestParsers.java
Outdated
Show resolved
Hide resolved
solr/core/src/java/org/apache/solr/request/SolrQueryRequest.java
Outdated
Show resolved
Hide resolved
solr/core/src/java/org/apache/solr/request/SolrQueryRequest.java
Outdated
Show resolved
Hide resolved
solr/core/src/java/org/apache/solr/request/SolrQueryRequest.java
Outdated
Show resolved
Hide resolved
solr/core/src/java/org/apache/solr/request/SolrQueryRequest.java
Outdated
Show resolved
Hide resolved
There was a problem hiding this comment.
Pull request overview
Copilot reviewed 14 out of 15 changed files in this pull request and generated 9 comments.
Comments suppressed due to low confidence (1)
solr/core/src/java/org/apache/solr/servlet/SolrRequestParsers.java:121
- There is a large block of commented-out code in
init()referencing removed fields/constants (e.g.,parsers,STANDARD,standard). Leaving this dead code around makes the refactor harder to follow and risks it getting stale. Prefer deleting it entirely or replacing it with a brief comment explaining the current design (singleStandardRequestParser).
private static RTimerTree getRequestTimer(HttpServletRequest req) {
final Object reqTimer = req.getAttribute(REQUEST_TIMER_SERVLET_ATTRIBUTE);
if (reqTimer instanceof RTimerTree) {
return ((RTimerTree) reqTimer);
}
return new RTimerTree();
}
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
| @@ -3131,14 +3131,11 @@ private void initWriters() { | |||
|
|
|||
| // Initialize with the built defaults | |||
| responseWriters.init(defaultWriters, this); | |||
There was a problem hiding this comment.
initWriters() no longer ensures a default response writer is set on responseWriters. If no <queryResponseWriter default="true"> is defined in solrconfig (e.g., configsets where response writers are only implicit), PluginBag's default (def) can remain null, which breaks default writer resolution and can change the default output unexpectedly. Consider restoring a safe default (e.g., set default to json) when responseWriters.getDefault() is null after init.
| responseWriters.init(defaultWriters, this); | |
| responseWriters.init(defaultWriters, this); | |
| // Ensure there is always a default response writer configured. | |
| // If no <queryResponseWriter default="true"> is defined and PluginBag | |
| // did not pick a default, fall back to "json" when available. | |
| if (responseWriters.getDefault() == null) { | |
| QueryResponseWriter jsonWriter = responseWriters.get("json", false); | |
| if (jsonWriter != null) { | |
| responseWriters.setDefault("json"); | |
| } | |
| } |
solr/core/src/java/org/apache/solr/response/ResponseWritersRegistry.java
Show resolved
Hide resolved
| QueryResponseWriter standardWriter = ResponseWritersRegistry.getWriter("json"); | ||
|
|
||
| // 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! | ||
| // These should all fall back to json | ||
| // I think this json thing is weird... I think it should throw an exception! | ||
| assertThat( | ||
| "geojson should fall back to standard", | ||
| "geojson should fall back to json", | ||
| ResponseWritersRegistry.getWriter("geojson"), | ||
| is(standardWriter)); | ||
| is(nullValue())); |
There was a problem hiding this comment.
In testBuiltInWriterLimitedSet, the local variable name (standardWriter) and the assertion message/comments say these formats "fall back to json", but the assertion expects nullValue(). Either update the test to assert the intended fallback behavior, or rename/update the comments/messages so they match the new contract (unknown built-in writer returns null).
|
|
||
| /** | ||
| * 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. |
There was a problem hiding this comment.
Grammar in this Javadoc is off: "Pass in a xml configuration" should be "Pass in an XML configuration" (and typically XML is capitalized).
| * Pass in a xml configuration. A null configuration will enable everything with maximum values. | |
| * Pass in an XML configuration. A null configuration will enable everything with maximum values. |
| NamedList<Object> res = cluster.getSolrClient().request(request); | ||
| String respString = InputStreamResponseParser.consumeResponseToString(res); | ||
|
|
There was a problem hiding this comment.
This test asserts on substrings like "500" in the raw response body, which is brittle (error pages/formatting can change). Since you already have the NamedList response from InputStreamResponseParser, consider asserting res.get("responseStatus") == 500 (and then optionally assert the message substring) for a more stable check.
|
@dsmiley assuming all the tests pass, this is ready for merging. |
|
| prometheusWriter, | ||
| ReplicationAPIBase.FILE_STREAM, | ||
| new FileStreamResponseWriter()); | ||
| Map.ofEntries( |
| 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. |
There was a problem hiding this comment.
minor: I prefer that we don't change source files for out-of-scope reasons that we aren't already touching for in-scope reasons.
There was a problem hiding this comment.
yeah, I really struggle with seeing these things and not fixing them. I will try not to do it in the futre. I swear I went through the entire code base and fixed all the typos, and yet I keep finding them.
There was a problem hiding this comment.
Are these changes in-scope?
There was a problem hiding this comment.
what's going on here?
note: commented code is typically avoided
| @SuppressWarnings({"unchecked"}) | ||
| public LocalSolrQueryRequest makeRequest(String... q) { | ||
| if (q.length == 1) { | ||
| args.computeIfAbsent("wt", k -> "xml"); |
There was a problem hiding this comment.
hmm... how did this end up failing without this?
Clarified the changelog entry by removing redundant information.
testSOLR59responseHeaderVersions looks like it tests wt, but the assertQ always sets wt=xml, so it doesn't do anything. We test qtime and status plenty of other places. I was confused by USELESS_OUTPUT till I realized it was part of UselessOutputWriter.
…null raw response writer
https://issues.apache.org/jira/browse/SOLR-18085
Description
The use of
wt=standardis odd.. It really means returnjsonformatted code. I dug around some more and we have werid complex logic around this parameter. Digging furthur, I think most of the complexity is not needed.The one thing that I DID change is that before if you did "wt=fake" then you would get JSON back in many places. And in the V2 api's if you did "wt=fake" you would get a 400 back with an error. I think the right think in either of those cases is a 500 server error.
Summary of 63d4284
I've updated the code so that when an invalid/unknown
wtparameter is provided, Solr returns a 500 Server Error instead of silently falling back or returning a null writer.Changes Made to default behavior:
SolrQueryRequest.java(lines 207-222):SolrExceptionwithSERVER_ERROR(500) when the response writer is not found for the givenwtparameterV2ApiIntegrationTest.java:testWTParamtest into two tests:testInvalidWTParamReturnsError- verifies thatwt=blehreturns a 500 error with the appropriate messagetestWTParam- verifies that when no wt is specified, JSON is used by defaultTestPrometheusResponseWriter.java:testUnsupportedMetricsFormatto clarify that unknown wt parameters return a 500 errorassertEquals(500, res.get("responseStatus"))which now passesSolution
Mostly refactoring, except for the big change in 63d4284 which changed the response logic.
Tests
Re ran test