Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

SolrRequest.getParams never null; and clarify mutability #3140

Open
wants to merge 5 commits into
base: main
Choose a base branch
from

Conversation

dsmiley
Copy link
Contributor

@dsmiley dsmiley commented Jan 27, 2025

SolrJ SolrRequest.getParams lacked javadocs and thus also clarity on null & mutability. This PR addresses that. It can return null but I don't want it to, so I made some changes and removed needless null checks. Too much code implicitly assumes it's non-null but that's an iffy assumption. Additionally mutability is unclear. So I propose that if the return type is ModifiableSolrParams, then it's safe to modify it. UpdateRequest had issues with this; I removed it's lazy instantiation so we can always count on an instance being returned that we can modify.

This PR introduces SolrParams.of(), the widespread usage of which can occur later. Or I could do all of this piece in another PR if asked.

Many changes here aren't strictly required but felt good with these changes.

https://issues.apache.org/jira/browse/SOLR-XXXXX

Copy link
Contributor Author

@dsmiley dsmiley left a comment

Choose a reason for hiding this comment

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

Solr 10 only, albeit could backport Solr.of, for example.

@@ -282,7 +282,6 @@ private void commitOnLeader(String leaderBaseUrl, String coreName)
throws SolrServerException, IOException {
try (SolrClient client = recoverySolrClientBuilder(leaderBaseUrl, coreName).build()) {
UpdateRequest ureq = new UpdateRequest();
ureq.setParams(new ModifiableSolrParams());
Copy link
Contributor Author

Choose a reason for hiding this comment

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

This was clearly a hack to work around it's weird mutability situation. Now not needed here and elsewhere.

UpdateRequest ureq = new UpdateRequest();
ureq.setParams(params);
ureq.getParams().set("versions", true);
Copy link
Contributor Author

Choose a reason for hiding this comment

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

With a clear mutability story, the requirement here is now easy with this one-liner. (same elsewhere)

Comment on lines -653 to +648
ureq.setParams(params);
ureq.getParams().add(params);
Copy link
Contributor Author

Choose a reason for hiding this comment

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

I chose to call SolrParams.add(SolrParams) here but could have called setParams. A nice effect of this is that we copy the params instead of use in-place. Previously this deleteDocAndGetVersion method actually added params to its argument, which is very bad taste.

Comment on lines +75 to +78
add.getParams()
.add("processor", "template")
.add("template.field", "x_s:key_{id}")
.add("commit", "true");
Copy link
Contributor Author

Choose a reason for hiding this comment

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

so nice IMO

Comment on lines -75 to +74
public void setParams(ModifiableSolrParams params) {
public void setParams(SolrParams params) {
Copy link
Contributor Author

Choose a reason for hiding this comment

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

getter & setter should have same type

Comment on lines -88 to +89
public ModifiableSolrParams getParams() {
public SolrParams getParams() {
Copy link
Contributor Author

Choose a reason for hiding this comment

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

With new clarity from the Javadocs, we should never declare the return type as ModifiableSolrParams unless we have a consistent instance to return.

@@ -40,8 +40,7 @@ public GenericV2SolrRequest(METHOD m, String path) {
* @param params query parameter names and values for making this request.
*/
public GenericV2SolrRequest(METHOD m, String path, SolrParams params) {
super(m, path);
this.params = params;
super(m, removeLeadingApiRoot(path), params);
Copy link
Contributor Author

Choose a reason for hiding this comment

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

@gerlowskija this includes a minor bug fix (to call removeLeadingApiRoot as the other overloaded constructor does) but maybe this code wasn't used

Comment on lines 128 to +130
// NOTE: if the update request contains only delete commands the params
// must be loaded now
if (updateRequest.getParams() == null) {
if (updateRequest.getParams().iterator().hasNext() == false) { // no params
Copy link
Contributor Author

Choose a reason for hiding this comment

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

This check is evil; took a while to find it as I debugged a test for hours. Behavior is changing based on the presence of params or not. Like nowhere is there a similar check (at least based on my adventure with this PR). The history behind these lines of code is what I consider to be an ugly/messy solution to propagating a commitWithin param. Tempting to add that on my long TODO list of messes to fix but our longer future is not "javabin", and the mess thankfully seems localized here.


public QueryRequest() {
super(METHOD.GET, null);
query = new ModifiableSolrParams(); // TODO SolrParams.of()
Copy link
Contributor Author

Choose a reason for hiding this comment

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

at some point I eventually added SolrParams.of; TODO to use it in more places

Copy link
Contributor

@gerlowskija gerlowskija left a comment

Choose a reason for hiding this comment

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

Left a few inline comments, but happy enough with things to give this a 'LGTM'

public abstract class AbstractUpdateRequest extends CollectionRequiringSolrRequest<UpdateResponse>
implements IsUpdateRequest {
protected ModifiableSolrParams params;
protected ModifiableSolrParams params = new ModifiableSolrParams(); // TODO make final
Copy link
Contributor

Choose a reason for hiding this comment

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

+1 to make this final. Otherwise it's tough to rely on the field being non-null, since the signature/contract lets folks set it to null.

That's my main concern about this PR in general - I love that we're saying that SolrRequest.getParams() always returns non-null. But I'm unsure how much confidence we can have in that guarantee while some SolrRequest implementations offer a setParams(...) method that would allow any SolrJ user to break that promise (in their client side code at least). Maybe javadocs on the setParams(...) methods is enough to address that? Or maybe something else in this PR already addresses that and I've just missed it?

((MirroredAdminRequest) request).setParams(params);
} else if (request instanceof UpdateRequest) {
((UpdateRequest) request).setParams(params);
if (request instanceof MirroredAdminRequest mReq) {
Copy link
Contributor

Choose a reason for hiding this comment

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

[+1] I haven't seen this instanceof-and-declare-variable syntax before - very cool!

Copy link
Contributor Author

Choose a reason for hiding this comment

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

yeah it's a very nice Java 16 thing

@dsmiley dsmiley marked this pull request as ready for review February 2, 2025 16:13
@dsmiley
Copy link
Contributor Author

dsmiley commented Feb 2, 2025

Not thinking a JIRA/CHANGES.txt is worth it but will do if asked.
Proposed commit message:

Clarify getParams not null in SolrRequest, SolrQueryRequest, QParser
Clarify mutability of params for SolrRequest (SolrJ). UpdateRequest changed; doesn't lazy-create params anymore.
New SolrParams.of() and of(key, value) for an empty or single-pair instance.

Planning to merge Tuesday if no further comments.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants