This is an automated email from the ASF dual-hosted git repository.

dsmiley pushed a commit to branch branch_9x
in repository https://gitbox.apache.org/repos/asf/solr.git


The following commit(s) were added to refs/heads/branch_9x by this push:
     new ba1daf74463 SOLR-18056: CloudSolrClient better urlScheme detection 
(from URL or solr.ssl.enabled) (#4162)
ba1daf74463 is described below

commit ba1daf744638a58b6d3a8fb6210747332d2f73ff
Author: Vishnu Priya <[email protected]>
AuthorDate: Thu Feb 26 22:50:06 2026 -0500

    SOLR-18056: CloudSolrClient better urlScheme detection (from URL or 
solr.ssl.enabled) (#4162)
    
    Improved CloudSolrClient's urlScheme detection by using the scheme of 
provided Solr URLs, or looking at "solr.ssl.enabled".
    
    Co-authored-by: David Smiley <[email protected]>
    
    (cherry picked from commit 1962fc69a1d8949a98d4dcd2b668ff0aae37de31)
---
 changelog/unreleased/SOLR-18056-urlScheme-csp.yml  |  8 +++
 .../solrj/impl/ZkClientClusterStateProvider.java   | 19 ++++++-
 .../cloud/DelegatingClusterStateProvider.java      |  8 +++
 .../solrj/impl/BaseHttpClusterStateProvider.java   |  8 ++-
 .../solr/client/solrj/impl/CloudSolrClient.java    |  2 +-
 .../client/solrj/impl/ClusterStateProvider.java    |  3 ++
 .../solrj/impl/ClusterStateProviderTest.java       | 63 ++++++++++++++++++++++
 7 files changed, 108 insertions(+), 3 deletions(-)

diff --git a/changelog/unreleased/SOLR-18056-urlScheme-csp.yml 
b/changelog/unreleased/SOLR-18056-urlScheme-csp.yml
new file mode 100644
index 00000000000..f7a3d2690b1
--- /dev/null
+++ b/changelog/unreleased/SOLR-18056-urlScheme-csp.yml
@@ -0,0 +1,8 @@
+# See https://github.com/apache/solr/blob/main/dev-docs/changelog.adoc
+title: Improved CloudSolrClient's urlScheme detection by using the scheme of 
provided Solr URLs, or looking at "solr.ssl.enabled".
+type: changed
+authors:
+  - name: Vishnu Priya Chandra Sekar
+links:
+  - name: SOLR-18056
+    url: https://issues.apache.org/jira/browse/SOLR-18056
diff --git 
a/solr/solrj-zookeeper/src/java/org/apache/solr/client/solrj/impl/ZkClientClusterStateProvider.java
 
b/solr/solrj-zookeeper/src/java/org/apache/solr/client/solrj/impl/ZkClientClusterStateProvider.java
index f9d202f5949..0a1ee9ab439 100644
--- 
a/solr/solrj-zookeeper/src/java/org/apache/solr/client/solrj/impl/ZkClientClusterStateProvider.java
+++ 
b/solr/solrj-zookeeper/src/java/org/apache/solr/client/solrj/impl/ZkClientClusterStateProvider.java
@@ -35,6 +35,7 @@ import org.apache.solr.common.cloud.SolrZkClient;
 import org.apache.solr.common.cloud.ZkNodeProps;
 import org.apache.solr.common.cloud.ZkStateReader;
 import org.apache.solr.common.cloud.ZooKeeperException;
+import org.apache.solr.common.util.EnvUtils;
 import org.apache.solr.common.util.Utils;
 import org.apache.zookeeper.KeeperException;
 import org.noggit.JSONWriter;
@@ -45,7 +46,7 @@ import org.slf4j.LoggerFactory;
 public class ZkClientClusterStateProvider
     implements ClusterStateProvider, SolrZkClientTimeoutAware {
   private static final Logger log = 
LoggerFactory.getLogger(MethodHandles.lookup().lookupClass());
-
+  private static final String SOLR_SSL_ENABLED = "solr.ssl.enabled";
   volatile ZkStateReader zkStateReader;
   private boolean closeZkStateReader = true;
   private final String zkHost;
@@ -339,4 +340,20 @@ public class ZkClientClusterStateProvider
   public void setZkClientTimeout(int zkClientTimeout) {
     this.zkClientTimeout = zkClientTimeout;
   }
+
+  /**
+   * @return url scheme with the help of cluster property or environment 
variable.
+   */
+  @Override
+  public String getUrlScheme() {
+    final Boolean isSolrSslEnabled = 
EnvUtils.getPropertyAsBool(SOLR_SSL_ENABLED);
+    if (isSolrSslEnabled != null) {
+      return isSolrSslEnabled ? "https" : "http";
+    }
+    final Object urlSchemeClusterProperty = 
getClusterProperty(ClusterState.URL_SCHEME);
+    if (urlSchemeClusterProperty != null) {
+      return urlSchemeClusterProperty.toString();
+    }
+    return "http";
+  }
 }
diff --git 
a/solr/solrj/src/java/org/apache/solr/client/solrj/cloud/DelegatingClusterStateProvider.java
 
b/solr/solrj/src/java/org/apache/solr/client/solrj/cloud/DelegatingClusterStateProvider.java
index 4177f0a017a..0ccaa7b25e9 100644
--- 
a/solr/solrj/src/java/org/apache/solr/client/solrj/cloud/DelegatingClusterStateProvider.java
+++ 
b/solr/solrj/src/java/org/apache/solr/client/solrj/cloud/DelegatingClusterStateProvider.java
@@ -141,4 +141,12 @@ public class DelegatingClusterStateProvider implements 
ClusterStateProvider {
     }
     return null;
   }
+
+  @Override
+  public String getUrlScheme() {
+    if (delegate != null) {
+      return delegate.getUrlScheme();
+    }
+    return null;
+  }
 }
diff --git 
a/solr/solrj/src/java/org/apache/solr/client/solrj/impl/BaseHttpClusterStateProvider.java
 
b/solr/solrj/src/java/org/apache/solr/client/solrj/impl/BaseHttpClusterStateProvider.java
index a7d6543c9b9..c7319ffaee9 100644
--- 
a/solr/solrj/src/java/org/apache/solr/client/solrj/impl/BaseHttpClusterStateProvider.java
+++ 
b/solr/solrj/src/java/org/apache/solr/client/solrj/impl/BaseHttpClusterStateProvider.java
@@ -74,11 +74,12 @@ public abstract class BaseHttpClusterStateProvider 
implements ClusterStateProvid
       Executors.newSingleThreadScheduledExecutor(
           new SolrNamedThreadFactory("liveNodeReloadingExecutor"));
 
-  protected void initConfiguredNodes(List<String> solrUrls) throws Exception {
+  protected void initConfiguredNodes(List<String> solrUrls) {
     this.configuredNodes =
         solrUrls.stream()
             .map(BaseHttpClusterStateProvider::stringToUrl)
             .collect(Collectors.toList());
+    this.urlScheme = this.configuredNodes.get(0).getProtocol();
   }
 
   private static URL stringToUrl(String solrUrl) {
@@ -454,6 +455,11 @@ public abstract class BaseHttpClusterStateProvider 
implements ClusterStateProvid
     liveNodeReloadingService.shutdown();
   }
 
+  @Override
+  public String getUrlScheme() {
+    return this.urlScheme;
+  }
+
   private enum ClusterStateRequestType {
     FETCH_LIVE_NODES,
     FETCH_CLUSTER_PROP,
diff --git 
a/solr/solrj/src/java/org/apache/solr/client/solrj/impl/CloudSolrClient.java 
b/solr/solrj/src/java/org/apache/solr/client/solrj/impl/CloudSolrClient.java
index 59a406e35d4..09c87decf2d 100644
--- a/solr/solrj/src/java/org/apache/solr/client/solrj/impl/CloudSolrClient.java
+++ b/solr/solrj/src/java/org/apache/solr/client/solrj/impl/CloudSolrClient.java
@@ -1215,7 +1215,7 @@ public abstract class CloudSolrClient extends SolrClient {
         requestRLTGenerator.getReplicaListTransformer(reqParams);
 
     final ClusterStateProvider provider = getClusterStateProvider();
-    final String urlScheme = 
provider.getClusterProperty(ClusterState.URL_SCHEME, "http");
+    final String urlScheme = provider.getUrlScheme();
     final Set<String> liveNodes = provider.getLiveNodes();
 
     final List<String> theUrlList = new ArrayList<>(); // we populate this as 
follows...
diff --git 
a/solr/solrj/src/java/org/apache/solr/client/solrj/impl/ClusterStateProvider.java
 
b/solr/solrj/src/java/org/apache/solr/client/solrj/impl/ClusterStateProvider.java
index ce7c7f9c2e4..439363f9149 100644
--- 
a/solr/solrj/src/java/org/apache/solr/client/solrj/impl/ClusterStateProvider.java
+++ 
b/solr/solrj/src/java/org/apache/solr/client/solrj/impl/ClusterStateProvider.java
@@ -127,4 +127,7 @@ public interface ClusterStateProvider extends SolrCloseable 
{
   void connect();
 
   String getQuorumHosts();
+
+  /** Get url scheme like http or https but never null. */
+  String getUrlScheme();
 }
diff --git 
a/solr/solrj/src/test/org/apache/solr/client/solrj/impl/ClusterStateProviderTest.java
 
b/solr/solrj/src/test/org/apache/solr/client/solrj/impl/ClusterStateProviderTest.java
index 488d816767d..fa2c6a32fee 100644
--- 
a/solr/solrj/src/test/org/apache/solr/client/solrj/impl/ClusterStateProviderTest.java
+++ 
b/solr/solrj/src/test/org/apache/solr/client/solrj/impl/ClusterStateProviderTest.java
@@ -27,6 +27,7 @@ import 
com.carrotsearch.randomizedtesting.annotations.ParametersFactory;
 import java.io.IOException;
 import java.lang.invoke.MethodHandles;
 import java.lang.reflect.InvocationTargetException;
+import java.nio.file.Path;
 import java.time.Instant;
 import java.util.List;
 import java.util.Map;
@@ -38,8 +39,13 @@ import org.apache.solr.client.solrj.SolrServerException;
 import org.apache.solr.client.solrj.request.CollectionAdminRequest;
 import org.apache.solr.client.solrj.response.CollectionAdminResponse;
 import org.apache.solr.cloud.SolrCloudTestCase;
+import org.apache.solr.cloud.ZkController;
+import org.apache.solr.cloud.ZkTestServer;
+import org.apache.solr.common.cloud.ClusterProperties;
 import org.apache.solr.common.cloud.ClusterState;
 import org.apache.solr.common.cloud.DocCollection;
+import org.apache.solr.common.cloud.SolrZkClient;
+import org.apache.solr.common.cloud.ZkStateReader;
 import org.apache.solr.common.util.NamedList;
 import org.eclipse.jetty.http.HttpField;
 import org.eclipse.jetty.http.HttpHeader;
@@ -49,6 +55,7 @@ import org.junit.BeforeClass;
 import org.junit.Test;
 
 public class ClusterStateProviderTest extends SolrCloudTestCase {
+  private static final String SOLR_SSL_ENABLED = "solr.ssl.enabled";
 
   @BeforeClass
   public static void setupCluster() throws Exception {
@@ -372,6 +379,62 @@ public class ClusterStateProviderTest extends 
SolrCloudTestCase {
     }
   }
 
+  @Test
+  public void testHttpClusterStateProviderUrlScheme() throws Exception {
+    final List<String> solrUrls =
+        List.of("https://localhost:8983/solr";, "https://localhost:8984/solr";);
+    try (var httpClient = new Http2SolrClient.Builder().build();
+        ClusterStateProvider clusterStateProvider =
+            new Http2ClusterStateProvider(solrUrls, httpClient)) {
+      assertEquals("https", clusterStateProvider.getUrlScheme());
+    }
+  }
+
+  @Test
+  public void testZkClusterStateProviderUrlScheme() throws Exception {
+    final Path zkDir = createTempDir("zkData");
+
+    final ZkTestServer server = new ZkTestServer(zkDir);
+    try {
+      server.run();
+      SolrZkClient client = new 
SolrZkClient.Builder().withUrl(server.getZkAddress()).build();
+      ZkController.createClusterZkNodes(client);
+      testUrlSchemeWithClusterProperties(client);
+      testUrlSchemeDefault(client);
+      testUrlSchemeWithSystemProperties(client);
+      client.close();
+    } finally {
+      server.shutdown();
+    }
+  }
+
+  private void testUrlSchemeDefault(SolrZkClient client) throws Exception {
+    try (var zkStateReader = new ZkStateReader(client);
+        var clusterStateProvider = new 
ZkClientClusterStateProvider(zkStateReader)) {
+      assertEquals("http", clusterStateProvider.getUrlScheme());
+    }
+  }
+
+  private void testUrlSchemeWithSystemProperties(SolrZkClient client) throws 
Exception {
+    System.setProperty(SOLR_SSL_ENABLED, "true");
+    try (var zkStateReader = new ZkStateReader(client);
+        var clusterStateProvider = new 
ZkClientClusterStateProvider(zkStateReader)) {
+      assertEquals("https", clusterStateProvider.getUrlScheme());
+    } finally {
+      System.clearProperty(SOLR_SSL_ENABLED);
+    }
+  }
+
+  private void testUrlSchemeWithClusterProperties(SolrZkClient client) throws 
Exception {
+    ClusterProperties cp = new ClusterProperties(client);
+    cp.setClusterProperty("urlScheme", "ftp");
+    try (var zkStateReader = new ZkStateReader(client);
+        var clusterStateProvider = new 
ZkClientClusterStateProvider(zkStateReader)) {
+      zkStateReader.createClusterStateWatchersAndUpdate();
+      assertEquals("ftp", clusterStateProvider.getUrlScheme());
+    }
+  }
+
   private void waitForCSPCacheTimeout() throws InterruptedException {
     Thread.sleep(2000);
   }

Reply via email to