This is an automated email from the ASF dual-hosted git repository.
HoustonPutman 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 cabedd1d968 SOLR-18487: Fix NPE For specific Jersey endpoints (#4973)
cabedd1d968 is described below
commit cabedd1d968059215188f4e7563fb303241899ed
Author: Houston Putman <[email protected]>
AuthorDate: Tue Oct 6 13:06:54 2026 -0700
SOLR-18487: Fix NPE For specific Jersey endpoints (#4973)
---
.../solr/cloud/api/collections/AdminCmdContext.java | 7 ++-----
.../apache/solr/handler/admin/CollectionsHandler.java | 5 ++++-
.../org/apache/solr/handler/admin/RebalanceLeaders.java | 5 ++++-
.../org/apache/solr/handler/admin/api/AdminAPIBase.java | 14 ++++++++++++--
.../java/org/apache/solr/jersey/InjectionFactories.java | 16 ++++++++++++++++
.../java/org/apache/solr/jersey/JerseyApplications.java | 13 +++++++++++++
6 files changed, 51 insertions(+), 9 deletions(-)
diff --git
a/solr/core/src/java/org/apache/solr/cloud/api/collections/AdminCmdContext.java
b/solr/core/src/java/org/apache/solr/cloud/api/collections/AdminCmdContext.java
index ee5f56deca1..e83f5bd245b 100644
---
a/solr/core/src/java/org/apache/solr/cloud/api/collections/AdminCmdContext.java
+++
b/solr/core/src/java/org/apache/solr/cloud/api/collections/AdminCmdContext.java
@@ -17,11 +17,8 @@
package org.apache.solr.cloud.api.collections;
-import static
org.apache.solr.common.params.CollectionAdminParams.CALLING_LOCK_ID_HEADER;
-
import org.apache.solr.common.cloud.ClusterState;
import org.apache.solr.common.params.CollectionParams;
-import org.apache.solr.request.SolrQueryRequest;
public class AdminCmdContext {
private final CollectionParams.CollectionAction action;
@@ -40,10 +37,10 @@ public class AdminCmdContext {
}
public AdminCmdContext(
- CollectionParams.CollectionAction action, String asyncId,
SolrQueryRequest req) {
+ CollectionParams.CollectionAction action, String asyncId, String
callingLockId) {
this.action = action;
this.asyncId = asyncId;
- this.withCallingLockId((String)
req.getContext().get(CALLING_LOCK_ID_HEADER));
+ this.callingLockId = callingLockId;
}
public CollectionParams.CollectionAction getAction() {
diff --git
a/solr/core/src/java/org/apache/solr/handler/admin/CollectionsHandler.java
b/solr/core/src/java/org/apache/solr/handler/admin/CollectionsHandler.java
index 34f4be920cf..170d3b69b52 100644
--- a/solr/core/src/java/org/apache/solr/handler/admin/CollectionsHandler.java
+++ b/solr/core/src/java/org/apache/solr/handler/admin/CollectionsHandler.java
@@ -311,7 +311,10 @@ public class CollectionsHandler extends RequestHandlerBase
implements Permission
}
AdminCmdContext adminCmdContext =
- new AdminCmdContext(operation.action, req.getParams().get(ASYNC), req);
+ new AdminCmdContext(
+ operation.action,
+ req.getParams().get(ASYNC),
+ (String) req.getContext().get(CALLING_LOCK_ID_HEADER));
ZkNodeProps zkProps = new ZkNodeProps(props);
final SolrResponse overseerResponse;
diff --git
a/solr/core/src/java/org/apache/solr/handler/admin/RebalanceLeaders.java
b/solr/core/src/java/org/apache/solr/handler/admin/RebalanceLeaders.java
index bff0be76ad3..1a435a1ad97 100644
--- a/solr/core/src/java/org/apache/solr/handler/admin/RebalanceLeaders.java
+++ b/solr/core/src/java/org/apache/solr/handler/admin/RebalanceLeaders.java
@@ -23,6 +23,7 @@ import static
org.apache.solr.common.cloud.ZkStateReader.LEADER_PROP;
import static org.apache.solr.common.cloud.ZkStateReader.MAX_AT_ONCE_PROP;
import static org.apache.solr.common.cloud.ZkStateReader.MAX_WAIT_SECONDS_PROP;
import static org.apache.solr.common.cloud.ZkStateReader.REJOIN_AT_HEAD_PROP;
+import static
org.apache.solr.common.params.CollectionAdminParams.CALLING_LOCK_ID_HEADER;
import static
org.apache.solr.common.params.CollectionParams.CollectionAction.REBALANCELEADERS;
import java.lang.invoke.MethodHandles;
@@ -460,7 +461,9 @@ class RebalanceLeaders {
// ignore response; we construct our own
collectionsHandler.submitCollectionApiCommand(
- new AdminCmdContext(REBALANCELEADERS, asyncId, req), new
ZkNodeProps(propMap));
+ new AdminCmdContext(
+ REBALANCELEADERS, asyncId, (String)
req.getContext().get(CALLING_LOCK_ID_HEADER)),
+ new ZkNodeProps(propMap));
}
// maxWaitSecs - How long are we going to wait? Defaults to 30 seconds.
diff --git
a/solr/core/src/java/org/apache/solr/handler/admin/api/AdminAPIBase.java
b/solr/core/src/java/org/apache/solr/handler/admin/api/AdminAPIBase.java
index faee1e61d72..cc270e61994 100644
--- a/solr/core/src/java/org/apache/solr/handler/admin/api/AdminAPIBase.java
+++ b/solr/core/src/java/org/apache/solr/handler/admin/api/AdminAPIBase.java
@@ -17,8 +17,11 @@
package org.apache.solr.handler.admin.api;
+import static
org.apache.solr.common.params.CollectionAdminParams.CALLING_LOCK_ID_HEADER;
import static
org.apache.solr.handler.admin.CollectionsHandler.DEFAULT_COLLECTION_OP_TIMEOUT;
+import jakarta.inject.Inject;
+import jakarta.inject.Named;
import java.util.Map;
import org.apache.solr.api.JerseyResource;
import org.apache.solr.client.api.model.AsyncJerseyResponse;
@@ -44,6 +47,10 @@ public abstract class AdminAPIBase extends JerseyResource {
protected final SolrQueryRequest solrQueryRequest;
protected final SolrQueryResponse solrQueryResponse;
+ @Inject
+ @Named(CALLING_LOCK_ID_HEADER)
+ protected String callingLockId;
+
public AdminAPIBase(
CoreContainer coreContainer,
SolrQueryRequest solrQueryRequest,
@@ -51,6 +58,9 @@ public abstract class AdminAPIBase extends JerseyResource {
this.coreContainer = coreContainer;
this.solrQueryRequest = solrQueryRequest;
this.solrQueryResponse = solrQueryResponse;
+ if (solrQueryRequest != null) {
+ callingLockId = (String)
solrQueryRequest.getContext().get(CALLING_LOCK_ID_HEADER);
+ }
}
protected CoreContainer fetchAndValidateZooKeeperAwareCoreContainer() {
@@ -138,7 +148,7 @@ public abstract class AdminAPIBase extends JerseyResource {
ZkNodeProps remoteMessage)
throws Exception {
return submitRemoteMessageAndHandleException(
- response, new AdminCmdContext(action, null, solrQueryRequest),
remoteMessage);
+ response, new AdminCmdContext(action, null, callingLockId),
remoteMessage);
}
protected SolrResponse submitRemoteMessageAndHandleAsync(
@@ -149,7 +159,7 @@ public abstract class AdminAPIBase extends JerseyResource {
throws Exception {
var remoteResponse =
submitRemoteMessageAndHandleException(
- response, new AdminCmdContext(action, asyncId, solrQueryRequest),
remoteMessage);
+ response, new AdminCmdContext(action, asyncId, callingLockId),
remoteMessage);
if (asyncId != null) {
response.requestId = asyncId;
diff --git a/solr/core/src/java/org/apache/solr/jersey/InjectionFactories.java
b/solr/core/src/java/org/apache/solr/jersey/InjectionFactories.java
index a3d6aa7daba..294d92b5170 100644
--- a/solr/core/src/java/org/apache/solr/jersey/InjectionFactories.java
+++ b/solr/core/src/java/org/apache/solr/jersey/InjectionFactories.java
@@ -17,12 +17,14 @@
package org.apache.solr.jersey;
+import static
org.apache.solr.common.params.CollectionAdminParams.CALLING_LOCK_ID_HEADER;
import static org.apache.solr.jersey.RequestContextKeys.SOLR_CORE;
import static org.apache.solr.jersey.RequestContextKeys.SOLR_PARAMS;
import jakarta.ws.rs.container.ContainerRequestContext;
import jakarta.ws.rs.core.Context;
import org.apache.solr.common.params.SolrParams;
+import org.apache.solr.common.util.StrUtils;
import org.apache.solr.core.SolrCore;
import org.apache.solr.request.SolrQueryRequest;
import org.apache.solr.response.SolrQueryResponse;
@@ -45,6 +47,20 @@ public class InjectionFactories {
public void dispose(SolrQueryRequest instance) {}
}
+ /** Provides the calling lock id header value, or null if absent or blank. */
+ public static class CallingLockIdFactory extends RequestContextBasedFactory
+ implements Factory<String> {
+
+ @Override
+ public String provide() {
+ String id = getRequestContext().getHeaderString(CALLING_LOCK_ID_HEADER);
+ return StrUtils.isBlank(id) ? null : id;
+ }
+
+ @Override
+ public void dispose(String instance) {}
+ }
+
public static class SolrQueryResponseFactory extends
RequestContextBasedFactory
implements Factory<SolrQueryResponse> {
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 559788b31a5..399117afd33 100644
--- a/solr/core/src/java/org/apache/solr/jersey/JerseyApplications.java
+++ b/solr/core/src/java/org/apache/solr/jersey/JerseyApplications.java
@@ -17,6 +17,8 @@
package org.apache.solr.jersey;
+import static
org.apache.solr.common.params.CollectionAdminParams.CALLING_LOCK_ID_HEADER;
+
import java.util.Map;
import org.apache.solr.common.params.SolrParams;
import org.apache.solr.core.SolrCore;
@@ -80,6 +82,17 @@ public class JerseyApplications {
}
});
+ register(
+ new AbstractBinder() {
+ @Override
+ protected void configure() {
+ bindFactory(InjectionFactories.CallingLockIdFactory.class)
+ .to(String.class)
+ .named(CALLING_LOCK_ID_HEADER)
+ .in(RequestScoped.class);
+ }
+ });
+
// Explicit Jersey logging is disabled by default but useful for
debugging (pt 1)
// register(LoggingFeature.class);